BufferedImage auf JPanel

papabaer1707

Aktives Mitglied
In vielen Beiträgen findet man die Möglichkeit auf JPanels mittels der Methode paintComponent zu zeichnen. Als Nachteil könnte sich hier herausstellen, dass ALLES in dieser Methode gezeichnet werden muss. Als eine Alternative, dies zu umgehen, wird die Verwendung eines BufferedImage genannt, welches dann zu gegebener Zeit (in PaintComponent) aufkopiert wird. Diesen Ansatz habe ich mal probiert umzusetzen, allerdings funktioniert es nicht richtig. Erst mal mein Ansatz:

Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.*;

public class PaintSWING extends JFrame {
    // Anfang Attribute
    private byte[][] myColorField = new byte[20][20];
    private BufferedImage zeichenImage;
    private MyCanvasPanel zeichenflaeche = new MyCanvasPanel(zeichenImage);
    private JButton btnDraw = new JButton();

    // Ende Attribute
    public PaintSWING(String title) {
        // Frame-Initialisierung
        super(title);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        int frameWidth = 510;
        int frameHeight = 572;
        setSize(frameWidth, frameHeight);

        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (d.width - getSize().width) / 2;
        int y = (d.height - getSize().height) / 2;
        setLocation(x, y);

        Container cp = getContentPane();
        cp.setLayout(null);
        // Anfang Komponenten
        zeichenflaeche.setBounds(7, 2, 500, 500);
        zeichenflaeche.setBackground(Color.WHITE);
        cp.add(zeichenflaeche);
        // Initialisieren / Angleichen der Zeichenflächen
        zeichenflaeche.init();
        btnDraw.setBounds(424, 512, 75, 25);
        btnDraw.setText("Draw");
        btnDraw.setMargin(new Insets(2, 2, 2, 2));
        btnDraw.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    btnDraw_ActionPerformed(evt);
                }
            });
        cp.add(btnDraw);
        // Ende Komponenten
        setResizable(false);
        setVisible(true);

        zeichenflaeche.repaint();
    }

    // Anfang Methoden
    public void btnDraw_ActionPerformed(ActionEvent evt) {
        Graphics g = zeichenImage.getGraphics();

        for (int x = 0; x < 19; x++) {
            for (int y = 0; y < 19; y++) {
                int ro = (int) Math.random()*255;
                int ge = (int) Math.random()*255;
                int bl = (int) Math.random()*255;
                g.setColor(new Color(ro, ge, bl));
                g.fillRect(x * 10, y * 10, 9, 9);
            }
        }
        zeichenflaeche.repaint();
    }

    // Ende Methoden
    public static void main(String[] args) {
        new PaintSWING("Zeichnen in SWING");
    }
}

... und ...

Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.*;

public class MyCanvasPanel extends JPanel {
    private BufferedImage zeichenImage;

    public MyCanvasPanel(BufferedImage zeichenImage) {
        this.zeichenImage = zeichenImage;
    }
    
    public void init() {
        zeichenImage = GraphicsEnvironment.getLocalGraphicsEnvironment()
                                          .getDefaultScreenDevice()
                                          .getDefaultConfiguration()
                                          .createCompatibleImage(this.getWidth(),
                this.getHeight());
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(zeichenImage, 0, 0, this);
    }
}

Nun meine Fragen:
  1. Der Zugriff scheint eigentlich zu funktionieren - nach dem Start erhalte ich ein schwarzes Bild. Dies müsste nach Durchlesen anderer Beiträge zu erwarten sein. Drücke ich jedoch auf den Button sehe ich keine Änderung :(. Liegt es am Zeichnen oder am Zugriff auf das Image beim Kopieren?
  2. Muss ich eigentlich die beiden Images (in den jeweiligen Methoden) angleichen, aslo die Methode init() verwenden? Sieht für mich ein bisschen komisch aus, ohne wirklich zu erkennen warum.
  3. Weshalb benötige ich hier eigentlich das @Override? Zum Überschreiben brauiche ich das sonst eigentlich nie ...
 
V

vanny

Gast
Versuchs mal mit
Java:
Graphics2D g = zeichenImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//...hier alle g.tueEtwasAktionen
g.dispose();
auf deinem BufferedImage

Gruß Vanny
 
Zuletzt bearbeitet von einem Moderator:

papabaer1707

Aktives Mitglied
Hm, musste erstmal noch etwas korrigieren:

Java:
private BufferedImage zeichenImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);

Aber die Änderung in Graphics2D zeigt keine Änderung.
 
Zuletzt bearbeitet:
V

vanny

Gast
hast du auch .createGraphics(); benutzt anstelle von .getGraphics(); ?
hast du dein g auch mit g.dispose(); geschlossen?

[EDIT]und 1x1Pixel ist auch recht klein :p[/EDIT]
 

papabaer1707

Aktives Mitglied
Jupp, genauso:

Java:
    public void btnDraw_ActionPerformed(ActionEvent evt) {
        Graphics2D g = zeichenImage.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        for (int x = 0; x < 19; x++) {
            for (int y = 0; y < 19; y++) {
                int ro = (int) Math.random()*255;
                int ge = (int) Math.random()*255;
                int bl = (int) Math.random()*255;
                g.setColor(new Color(ro, ge, bl));
                g.fillRect(x * 10, y * 10, 9, 9);
            }
        }
        g.dispose();
        zeichenflaeche.repaint();
    }

Das finale Bild müsste ein 20x20-Bild sein, bei dem jedes Quadrat die Kantenlänge 10px hat ...
 
Zuletzt bearbeitet:

xehpuk

Top Contributor
Liegt an deinem
Code:
init()
, welches
Code:
zeichenImage
einfach als neues BufferedImage setzt. Im Code von PaintSWING malst du aber auf der alten Referenz rum.
 

papabaer1707

Aktives Mitglied
Hm, wenn ich das init rausnehme, habe ich den gleichen Effekt, nur dass die ganze Fläche weiß statt schwarz ist - gezeichnet wird trotzdem nichts. Kann es dann hier daran liegen, dass die Größe nicht stimmen?

Kann das zwar ändern:
Java:
    private BufferedImage zeichenImage = new BufferedImage(1000,1000,BufferedImage.TYPE_INT_RGB);

... nur die Größe wäre am Besten genauso groß, wie die Zeichenfläche.
 
Zuletzt bearbeitet:
V

vanny

Gast
habs mal so nachgebaut:
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;


public class ZeichenPanel extends JPanel{

	private static final long serialVersionUID = 1L;
	private BufferedImage bim;
	private int rasterX = 19, rasterY = 19, tilesWidth = 9, tilesHeight = 9;
	
	public ZeichenPanel(){
		zeichneImage();
		repaint();
	}
	
	private void zeichneImage(){
		bim = new BufferedImage(rasterX*tilesWidth, rasterY*tilesHeight, BufferedImage.TYPE_INT_RGB);
		
		Graphics2D g2d = bim.createGraphics();
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		for (int x = 0; x < rasterX; x++) {
            for (int y = 0; y < resterY; y++) {
                int ro = (int) Math.random()*255;
                int ge = (int) Math.random()*255;
                int bl = (int) Math.random()*255;
                System.out.println(ro + ", " + ge + ", " + bl);
                g2d.setColor(new Color(ro, ge, bl));
                g2d.fillRect(x * (tilesWidth+1), y * (tilesHeight+1), tilesWidth, tilesHeight);
            }
        }
        g2d.dispose();
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		if(bim != null){
			g.drawImage(bim, 0, 0, bim.getWidth(), bim.getHeight(), null);
		}
	}
}

und das sysout gibt nur "0, 0, 0" also is das mit dem schwarzen bild kein Wunder :p

[EDIT]
ich bin mal nich so
Java:
int ro = (int) (Math.random()*255);
                int ge = (int) (Math.random()*255);
                int bl = (int) (Math.random()*255);
löst dein Problem :p
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

papabaer1707

Aktives Mitglied
Oje, so ein Fehler - lasse den ständig auf 0 rumhüpfen.

Scheint nun ganz gut zu funktionieren - hatte ja doch die richtigen Ideen (bis auf eine Ausnahme :)).

Wie kann ich nun die Größen anpassen. Im Grunde kann ich die Größe des Image so groß machen, dass es keine Probleme gibt. Ist das egal, oder macht es überhaupt Sinn diese Anpassung vorzunehmen?
 
V

vanny

Gast
schau dir meinen Code an, da is die Größe je nach Raster und Rechteckgröße angepasst.

...oder wie darf man deine Frage verstehen?

[EDIT]
habs nochmal angepasst
Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;


public class ZeichenPanel extends JPanel{

	private static final long serialVersionUID = 1L;
	private BufferedImage bim;
	private int rasterX = 19, rasterY = 19, tilesWidth = 9, tilesHeight = 9;
	
	public ZeichenPanel(){
		zeichneImage();
		repaint();
	}
	
	private void zeichneImage(){
		bim = new BufferedImage(rasterX*(tilesWidth+1), rasterY*(tilesHeight+1), BufferedImage.TYPE_INT_RGB);
		this.setPreferredSize(new Dimension(bim.getWidth(), bim.getHeight()));
		Graphics2D g2d = bim.createGraphics();
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		for (int x = 0; x < 19; x++) {
            for (int y = 0; y < 19; y++) {
                int ro = (int) (Math.random()*255);
                int ge = (int) (Math.random()*255);
                int bl = (int) (Math.random()*255);
                System.out.println(ro + ", " + ge + ", " + bl);
                g2d.setColor(new Color(ro, ge, bl));
                g2d.fillRect(x * (tilesWidth+1), y * (tilesHeight+1), tilesWidth, tilesHeight);
            }
        }
        g2d.dispose();
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		if(bim != null){
			g.drawImage(bim, 0, 0, bim.getWidth(), bim.getHeight(), null);
		}
	}
}
dann in deinem JFrame nochmal pack(); und es passt.
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

papabaer1707

Aktives Mitglied
schau dir meinen Code an, da is die Größe je nach Raster und Rechteckgröße angepasst.
Ja, das stimmt, nur ist dieses (wenn auch künstlerisch wertvolle) Bild nur als Beispiel gedacht. Gezeichnet werden könnten ja beliebige Figuren. Bei mir habe ich ich ein Panel mit einer vorgegebenen Größe und ein Image, welches ich gerne an diese Größe (automatisch) anpassen möchte. Ich denke mal, dass ich das zu kompliziert sehe ... ich kenne die Größe des Panels, also gebe ich die Größe des Images so ein - automatisch wäre nur schöner :)

... sehe schon - war zu schnell für deine Ergänzung ...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D JPanel Graphic2D als BufferedImage Speichern AWT, Swing, JavaFX & SWT 5
J JPanel in Bufferedimage AWT, Swing, JavaFX & SWT 3
R JPanel - BufferedImage - zeichnen großer Bilder AWT, Swing, JavaFX & SWT 2
I Arbeitsspeicherverbrauch BufferedImage.TYPE_INT_RGB vs. TYPE_3BYTE_BGR AWT, Swing, JavaFX & SWT 6
H BufferedImage zurücksetzen funktioniert nicht AWT, Swing, JavaFX & SWT 12
L AWT Ändern der Farbe eines BufferedImage mit Farbähnlichkeit AWT, Swing, JavaFX & SWT 5
I GEmaltes BufferedImage löschen AWT, Swing, JavaFX & SWT 3
cool_brivk24 BufferedImage einem ClickEvent hinzufügen AWT, Swing, JavaFX & SWT 13
cool_brivk24 AWT BufferedImage wird nicht geladen AWT, Swing, JavaFX & SWT 17
J linken Bildausschnitt eines BufferedImage abschneiden AWT, Swing, JavaFX & SWT 4
Zar von Domarus JFrame zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 3
S 2D-Grafik User-BufferedImage rotieren im Zentrum und ohne "anpassung" AWT, Swing, JavaFX & SWT 2
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
G Subimage von BufferedImage speichern AWT, Swing, JavaFX & SWT 4
D BufferedImage -> Feature Extraktion. Unterschiedliche BufferedImage imageTypes problem AWT, Swing, JavaFX & SWT 4
I 2D-Grafik Shape aus BufferedImage "löschen" AWT, Swing, JavaFX & SWT 2
M 2D-Grafik LookupOp Operation auf BufferedImage AWT, Swing, JavaFX & SWT 7
GianaSisters 2D-Grafik BufferedImage.getSubimage - Frage AWT, Swing, JavaFX & SWT 7
P BufferedImage schlechte Qualität beim Abspeichern AWT, Swing, JavaFX & SWT 9
S BufferedImage als schwarz-weiß-Bild AWT, Swing, JavaFX & SWT 3
Luk10 BufferedImage[...].getData() vs BufferedImage.setRGB() AWT, Swing, JavaFX & SWT 2
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
J Flackern wie mit BufferedImage beheben AWT, Swing, JavaFX & SWT 4
N Swing BufferedImage neu laden AWT, Swing, JavaFX & SWT 10
N 2D-Grafik BufferedImage, Line2D, Swing und die Probleme AWT, Swing, JavaFX & SWT 5
Luk10 BufferedImage auf ein anderes BufferedImage zeichnen AWT, Swing, JavaFX & SWT 6
K 2D-Grafik BufferedImage eingelesen, welches Modell?! AWT, Swing, JavaFX & SWT 2
T BufferedImage bei paintComponent AWT, Swing, JavaFX & SWT 6
C 2D-Grafik BufferedImage laden, Frage zum Code AWT, Swing, JavaFX & SWT 2
0x7F800000 2D-Grafik int[] zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 27
H 2D-Grafik BufferedImage aus Integer-Array AWT, Swing, JavaFX & SWT 3
Luk10 2D-Grafik BufferedImage sauber rotieren AWT, Swing, JavaFX & SWT 16
P Image mehrfach in ein BufferedImage zeichnen AWT, Swing, JavaFX & SWT 7
A BufferedImage nach dem Speichern immer schwarz AWT, Swing, JavaFX & SWT 8
J Bild aus Datei in BufferedImage laden AWT, Swing, JavaFX & SWT 4
E BufferedImage Alphaknal ein- und ausblenden AWT, Swing, JavaFX & SWT 7
N BufferedImage zeichnen AWT, Swing, JavaFX & SWT 4
D BufferedImage Größe skalieren AWT, Swing, JavaFX & SWT 2
P Swing Vom BufferedImage bei paintComponent nur soviel zeichnen, wie nötig AWT, Swing, JavaFX & SWT 3
B 2D-Grafik BufferedImage Performance AWT, Swing, JavaFX & SWT 3
Y frage zu BufferedImage AWT, Swing, JavaFX & SWT 7
E AWT RenderedImage aus BufferedImage erzeugen, um Bild abzuspeichern? AWT, Swing, JavaFX & SWT 4
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
A 2D-Grafik BufferedImage wird nicht eingezeichnet AWT, Swing, JavaFX & SWT 3
G 2D-Grafik BufferedImage Hintergrund immer schwarz AWT, Swing, JavaFX & SWT 4
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
J AWT BufferedImage to 2DArray AWT, Swing, JavaFX & SWT 10
R Bild drehen UND skalieren (Image bzw BufferedImage) AWT, Swing, JavaFX & SWT 5
1 BufferedImage in byte[], dann in String und zurück AWT, Swing, JavaFX & SWT 7
J Swing paintComponent() - repaint() - BufferedImage anzeigen AWT, Swing, JavaFX & SWT 5
C BufferedImage-Fehler? Falsches Bild wir gezeichnet AWT, Swing, JavaFX & SWT 5
B BufferedImage Builder AWT, Swing, JavaFX & SWT 15
F Transparentes BufferedImage über BufferedImage AWT, Swing, JavaFX & SWT 12
F Größe von BufferedImage ändern AWT, Swing, JavaFX & SWT 27
I Swing JComponent als BufferedImage speichern AWT, Swing, JavaFX & SWT 18
Dragonfire Swing Zoom-Vorgang optimieren [BufferedImage] AWT, Swing, JavaFX & SWT 2
2 Memory Leak mit BufferedImage !! AWT, Swing, JavaFX & SWT 15
X BufferedImage maximiert in JFrame anzeigen? AWT, Swing, JavaFX & SWT 2
R JTable - TableCellRenderer - BufferedImage AWT, Swing, JavaFX & SWT 9
D BufferedImage und Graphics2D AWT, Swing, JavaFX & SWT 3
R Zeichnen von Zahlen in BufferedImage AWT, Swing, JavaFX & SWT 6
G BufferedImage.getRGB() mit 3 int-Werten vergleichen AWT, Swing, JavaFX & SWT 2
Luma BufferedImage wird nicht gezeichnet AWT, Swing, JavaFX & SWT 3
G keine ScaledInstance von BufferedImage? AWT, Swing, JavaFX & SWT 6
S BufferedImage & Scaling: Altes Problem im neuen Gewand AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
G BufferedImage und jpg --> maximale Qualität AWT, Swing, JavaFX & SWT 9
F HTML Text irgendwie auf BufferedImage bringen AWT, Swing, JavaFX & SWT 3
R BufferedImage Problem AWT, Swing, JavaFX & SWT 2
G Problem mit BufferedImage und imageIO AWT, Swing, JavaFX & SWT 2
S BufferedImage drehen AWT, Swing, JavaFX & SWT 3
? ActionListener auf BufferedImage AWT, Swing, JavaFX & SWT 11
M BufferedImage mit html interpretierten String beschriften AWT, Swing, JavaFX & SWT 3
A Probelme mit großen BufferedImage in paintComponent AWT, Swing, JavaFX & SWT 7
B Farbtiefe eines BufferedImage verringern AWT, Swing, JavaFX & SWT 3
F ImageIcon -> BufferedImage AWT, Swing, JavaFX & SWT 2
T Performance Problem bei BufferedImage AWT, Swing, JavaFX & SWT 3
F Animiertes Gif als BufferedImage AWT, Swing, JavaFX & SWT 10
L Anzeigen von fotos: ImageIcon oder BufferedImage + paint() ? AWT, Swing, JavaFX & SWT 5
C Rotate BufferedImage --> Bild unvollständig AWT, Swing, JavaFX & SWT 5
U Streifen hinter bewegtem BufferedImage AWT, Swing, JavaFX & SWT 13
M BufferedImage skalieren AWT, Swing, JavaFX & SWT 6
T BufferedImage verkleinern Resultat ist zu pixelig. AWT, Swing, JavaFX & SWT 6
G Image Object speichern oder in ein BufferedImage umwandeln AWT, Swing, JavaFX & SWT 2
P Problem beim Zeichnen auf ein BufferedImage AWT, Swing, JavaFX & SWT 4
B BufferedImage aus einer Datei AWT, Swing, JavaFX & SWT 4
C Farben in BufferedImage ändern ? AWT, Swing, JavaFX & SWT 2
J Image to BufferedImage AWT, Swing, JavaFX & SWT 5
T BufferedImage kopieren AWT, Swing, JavaFX & SWT 3
T BufferedImage Farbe "Transparent" AWT, Swing, JavaFX & SWT 21
T BufferedImage + bestimmten bereich ausfüllen AWT, Swing, JavaFX & SWT 3
M BufferedImage Größe? AWT, Swing, JavaFX & SWT 10
U Löschen eines BufferedImage AWT, Swing, JavaFX & SWT 7
J Image aus BufferedImage ohne AWT AWT, Swing, JavaFX & SWT 5
V Image in BufferedImage AWT, Swing, JavaFX & SWT 3
J BufferedImage aus byte-Array erstellen AWT, Swing, JavaFX & SWT 3
P Zwei JPanel übereianderlegen AWT, Swing, JavaFX & SWT 14
XWing Basic JPanel mit 2 Buttons beutzen. AWT, Swing, JavaFX & SWT 10

Ähnliche Java Themen

Neue Themen


Oben