Pixel zeichnen

Status
Nicht offen für weitere Antworten.

Roland

Mitglied
Hallo Leute,

ich habe hier ein kleines Problem und komme nicht so recht dahinter.
Ich versuche ein Bild zeichnen zu lassen, dass ich vorher in ein int-Array gespeichert habe.
Breite und Höhe sind auch bekannt.
Die RGB-Werte sind entsprechend gespeichert, also x[0] = rot-Wert, x[1] = grün, x[2] = blau usw.

Wenn ich es so versuche wie bis jetzt, dann bekomme ich nen schwarzen Kasten raus und nicht
das schöne rote auto, dass das Bild zeigt 🙂

Hier mal der Code:

Code:
import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class PicViewer extends JFrame{
	public PicViewer () {

		this.setTitle("PicViewer");
		this.setSize(300, 200);
		this.setResizable(false);
		this.setBackground(new Color(100,100,100));
		this.setLocation(100, 50);
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		
		// content
		JPanel panel = new JPanel(new BorderLayout());
		
		this.add(panel);
		this.setVisible(true);
	}
	
	public void draw(int[] pixels, int width, int height) {
		 
		int widthm3 = width*3;  
         for (int i = 0; i < pixels.length; i+=3) {
        	 int r = pixels[i];
        	 int g = pixels[i+1];
        	 int b = pixels[i+2];
        	 	Color z = new Color(r, b, g);
                        this.getGraphics().setColor(z);  
                        this.getGraphics().drawLine((i%widthm3)/3, i/widthm3, (i%widthm3)/3, i/widthm3);  
         }
        
	}

}

Hat jemand nen vorschlag?
Oder einfach nur tipps wie man´s schöner machen könnte?

Prämisse ist aber, dass ich das Bild aus dem Int-Array lesen muss...

Vielen Dank schon mal,

MfG
Roland
 
Mal davon abgesehen, das mir die Funktionsweise der draw-Methode irgendwie nicht klar ist, folgende Anmerkungen:

- die draw-Methode wird nirgends aufgerufen
- damit etwas angezeigt wird, mußt Du nach dem Zeichnen einen repaint() machen
- getGraphics()... tutet man nicht - nie! (also fast nie, bevor wieder jemand weint.. 😉).

Nimm eine eigene Komponente, die von JPanel erbt und überschreibe die paintComponent-Methode. Dort packst Du dann rein, was Du jetzt in der draw-Methode hast (ohne den getGraphics()-Schlonz, da paintComponent() ein GrafikObjekt übergben bekommt).
Diese eigene Komponente addest Du dann anstelle des JPanel in Dein JFrame und dann solltest Du auch was angezeigt bekommen.
 
Danke für den Tipp.

Werds mal so probieren.

Die draw-Methode wird von nem Controller aufgerufen. Ich gebe zu, hätt ich erwähnen sollen 🙂

drawLine() zeichnet ne Linie, in dem Fall halt nur eine die 1en Pixel lang ist. Hab keinen besseren Weg
gefunden einzelne Pixel zu zeichnen.
 
In diesem Fall wäre es vmtl. besser (d.h. DEUTLICH effizienter) den Array nur EIN mal in ein BufferedImage reinzumalen, und in der paintComponent dann nurnoch das BufferedImage zu malen.

In einem BufferedImage kann man die Pixel direkt setzen, und braucht nicht drawLine zu machen.

Code:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

public void updateImage(array...)
{
    for (x...)
    {
        for (y...)
        {
            int r = array[x,y,0];
            int g = array[x,y,1];
            int b = array[x,y,2];
            int rgb = (r<<16) | (g<<8) | b;
            image.setRGB(x,y, rgb);
        }
    }
}

...

public void paintComponent(Graphics g)
{
    g.drawImage(image,0,0,this);
}
 
In Bezug auf die einzelnen Pixel hätte ich folgenden Vorschlag:

- erstelle Dir im Konstruktor ein BufferedImage in der Größe der Komponent/Zeichnung
- diese BufferedImage zeichnest Du in der paintComponent-Methode mit drawImage(...)
- Deine eigentliche Zeichenarbeit machst Du vorher in diesey BufferedImage
- in diesem BufferedImage kannst Du mit setRGB(int x, int y, int rgb) einzelnen Pixel einfärben
- den Integer rgb bekommt man z. B. über eine Color-Objekt mit getRGB()
 
Kannst du mir erklären, was das hier macht?

Code:
            int r = array[x,y,0];
            int g = array[x,y,1];
            int b = array[x,y,2];
            int rgb = (r<<16) | (g<<8) | b;
 
Ohne zu Wissen, was jetzt x und y an der Ecke sind, wird hier offensichtlich über Bit-Verschiebung ein integer in der Form zusammen gebaut, wie Du ihn in der 3. Variable der Methode setRGB(...) benötigst.

Im Prinzip könnte man z.B. auch schreiben:

Color c = new Color(r,g,b);
c.getRGB();
 
Anonymous hat gesagt.:
Kannst du mir erklären, was das hier macht?
...

Vielleicht sollte ich erwähnen, dass

int r = array[x,y,0];

Pseudocode ist, und so viel bedeuten soll wie: "r ist die Rot-Komponente des Pixels an der Position x,y". (Wie genau das in deinem Array abgespeichert ist, hatte ich nicht nachvollzogen). Man kann sich das RGB auch so holen, wie Quaxli es beschrieben hat, aber das ist u.U. deutlich langsamer (weil jedes mal ein neues Color-Objekt erstellt wird, was eigentlich überflüssig ist)

Das
int rgb = (r<<16) | (g<<8) | b;
kombiniert die Rot- Grün und Blau-Anteile eines Pixels in EINEN int, so dass man diesen Pixel direkt im BufferedImage mit der gewünschten RGB-Farbe setzen kann.
 
Danke für die Erklärungen und die Hilfe 🙂

Schon wieder was gelernt.

So funktionierts jetzt:

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class PicPanel extends JPanel{
	BufferedImage bufPic;
	int[] panPixels;
	int panWidth;
	int panHeight;
	
	public PicPanel(int[] pixels, int width, int height) {
		super();
		panPixels = new int[pixels.length];
		panPixels = pixels;
		panWidth = width;
		panHeight = height;
		bufPic = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		this.updateImage(panPixels, panWidth, panHeight);
	}
	
	public void updateImage(int[] panPixels, int panWidth, int panHeight)
	{
		int widthm3 = panWidth*3;  
        for (int i = 0; i < panPixels.length; i+=3) {
       	 int r = panPixels[i];
       	 int g = panPixels[i+1];
       	 int b = panPixels[i+2];

       	 int rgb = (r<<16) | (g<<8) | b;                 
            bufPic.setRGB((i%widthm3)/3, i/widthm3, rgb);  
        }       
		
	} 
	
	// called when painted
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(bufPic,0,0,this);
	}
}

Grüße
Roland
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben