Swing JComponent als BufferedImage speichern

Status
Nicht offen für weitere Antworten.

icarus2

Top Contributor
Hi

Ich habe gerade in ein bestehendes Projekt eingebaut, dass der Benutzer auswählen kann, dass er das Bild einer JComponent speichern kann, auf dem Desktop. Es wird da ein Ornder erstellt und das Bild wird auch korrekt als jpg abgespeichert.

Folgendes Problem:
Das Bild ist einfach schwarz. Ich kann mir nicht erklären warum das so ist.

Ich habe folgenden Code:
[Java]
BufferedImage image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
[/Java]

Hinweis:
Das ganze läuft in einem eigenen Thread ab. In diesem Thread wird das Bild immer neu gezeichnet. Ist das vielleicht das Problem? Ich kann mir das nicht vorstellen, denn die JComponent wird erst neu gezeichnet, wenn das Bild bereits gespeichert wurde. Hat da jmd eine Idee?
 

Marco13

Top Contributor
Ein KSKB könnte helfen. Hast du mal (nur testweise) dort, wo du die Component in's Bild malst, stattdessen ein
imageGraphics.setColor(Color.RED);
imageGraphics.drawString("Haaaalllooo", 30, 30);
gemacht, um zu schauen, ob das Problem beim Zeichnen selbst oder beim Abspeichern liegt?
 

icarus2

Top Contributor
Also das Zeichnen funktioniert schon, so wie ich das sehe. Ich habe hier kurz ein vereinfachtest Beispiel gemacht:

Haupt-Klasse:
[Java]
package frame;

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;

public class Main extends JFrame {

Container c;
TestPanel tp;

public Main(){

c = getContentPane();

tp = new TestPanel();
tp.setBorder(new TitledBorder("TestPanel"));

c.add(tp, BorderLayout.CENTER);

setSize(600, 600);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


}

public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
new Main();
}
});
}

}
[/Java]

Und hier die von JComponent abgeleitete Klasse:
[Java]
package frame;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class TestPanel extends JComponent implements KeyListener {

private File desktopDirectory; //path to desktop of the user

public TestPanel(){

desktopDirectory = new File(System.getProperty("user.home") + "/Desktop/images");
desktopDirectory.mkdir();

setFocusable(true);
addKeyListener(this); //if enter is pressed, a screenshot of the jcomponent is stored on the desktop
}

private void storeImage(){

BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
writeImageToDesktop(image, "TestImage");

}


public void writeImageToDesktop(BufferedImage image, String imageName){

try {
File outPutFile = new File(desktopDirectory.getAbsolutePath()+ "/" + imageName +".jpg");
ImageIO.write(image, "jpg", outPutFile);
}catch(IOException e){
e.printStackTrace();
}
}

@Override
public void paintComponent(Graphics g){
super.paintComponent(g);

g.setColor(Color.red);

g.fillOval(20, 20, 200, 300);
}

@Override
public void keyPressed(KeyEvent e) {}

@Override
public void keyReleased(KeyEvent e) {

if(e.getKeyCode() == KeyEvent.VK_ENTER){
storeImage();
System.out.println("image stored");
}

}

@Override
public void keyTyped(KeyEvent e) {}

}

[/Java]

Wenn du Enter klickst, dann sollte die JComponent als Bild auf deinem Desktop im Ordner images gespeichert werden. Das Bild ist dann allerdings nur schwarz.

Ich bin atm grad etwas überfordert iwie. Kannst du daraus erkennen, was nicht gut ist?
 

Arbon

Bekanntes Mitglied
Also so wie ich das sehe, erstellst du einfach ein neues Bild mit den gewünschten Dimensionen und speicherst das dann ab. Du musst schon etwas auf dein bild raufzeichnen, sonst bleibt es natürlich leer. Eine einfache Möglichkeit wäre es sicher, mit der Robot Klasse einen Screenshot vom gewünschten Bereich zu machen und diesen abzuspeichern.
 

icarus2

Top Contributor
Danke, das mit der Robot Klasse hat mir sehr geholfen. Das Bild wird jetzt tatsächlich richtig gezeichnet =)

Ich muss jetzt nur noch herausfinden, wie ich die Koordinaten am besten abstimme. Aber das sollte ich schon noch hinbekommen, sonst frage ich hier nach.

Vielen Dank für die Hilfe =)
 

Marco13

Top Contributor
Neee, lass' das mal mit dem Robot. Dafür ist der eigentlich nicht da. Was du vorhast geht eher in Richtung von
Code:
    private void storeImage(){

        BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);

        [b]paint(image.getGraphics());[/b]

        writeImageToDesktop(image, "TestImage");

    }
(das Problem mit dem Robot könnte man mit den SwingUtilities lösen, aber das nur nebenbei...)
 

icarus2

Top Contributor
Also das mit dem paint() funktioniert ja schon mal recht gut =)

(Und ich darf sogar mal getGraphics() verwenden... gemäss aussagen, die ich hier im Forum gehört habe, dürfte ich mich jetzt also schon zu den Pros zählen ^^ ... naja, vielleicht auch doch nit ganz :D)

Es gibt allerdings ein Problem:
Der Hintergrund (in der Standardfarbe von einer JComponent) wird jedes mal entweder schwarz oder weiss gezeichnet... immer abwechseln. Gibt es dafür einen bestimmten Grund?

Die Methode in einer externen Klasse sieht so aus:
[Java]
public void writeImageToDesktop(JComponent component, Point absoluteLocation, int width, int height, int solutionNumber){


BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
component.paint(image.getGraphics());


try {
File outPutFile = new File(desktopDirectory.getAbsolutePath()+ "/solution " + solutionNumber +".jpg");
ImageIO.write(image, "jpg", outPutFile);
}catch(IOException e){
e.printStackTrace();
}
}
[/Java]
 
B

Beni

Gast
(Und ich darf sogar mal getGraphics() verwenden... gemäss aussagen, die ich hier im Forum gehört habe, dürfte ich mich jetzt also schon zu den Pros zählen ^^ ... naja, vielleicht auch doch nit ganz :D)
Dieses getGraphics ist nicht so böse wie das andere getGraphics. Obwohl... eigentlich wäre ja "createGraphics" besser. Und beim erstellten Graphics-Object sollte man auch "dispose" aufrufen, wenn man es nicht mehr braucht.

Zu den Hintergrundfarben: füll das Bild doch einfach zuerst mit einer Farbe auf, das könnte helfen.
 

icarus2

Top Contributor
So besser?
[Java]
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
component.paint(image.createGraphics());
[/Java]

Dumme Frage... aber wie kann ich ein BufferedImage einfach ganz auf Weiss setzen? Sry, hört sich vielleicht echt dumm an, aber ich habe gerade keine passende Methode dafür gefunden :/
 

Michael...

Top Contributor
So auf die Schnelle könnte folgendes funktionieren: (untestet!!)
Java:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.setColor(Color.WHITE);
g.drawRect(0, 0, image.getWidth(), image.getHeight());
 

icarus2

Top Contributor
Hmm, nein, das funktioniert leider überhaupt nicht.

Kann mir jemand sagen, wie ich ein Bild erzeugen kann, das zu Beginn einen weissen Hintergrund hat?

*Edit:
Merkwürdigerweise funktioniert der Code von Marco einwandfrei, wenn ich die Klasse von JPanel ableite und nicht von JComponent. Hat wer ne Erklärung dafür?
 
Zuletzt bearbeitet:

andre111

Bekanntes Mitglied
Vermutlich ist die JComponent, die du auf das Bild zeichnest nicht opak und es wird kein Hintergrund gezeichnet (setOpaque(true), dann sollte es gehen). Ein JPanel ist anfangs immer opak.
 

Schandro

Top Contributor
Michael...'s Code zum füllen eines BufferedImage's mit weißer Farbe ist im Prinzip richtig, es muss nur fillRect statt drawRect heissen...
 

icarus2

Top Contributor
@andre111:
Achso, ja stimmt. Hatte das mal gelesen, aber wieder vergessen ^^

@Schandro:
Ok, ich werds nochmal versuchen. Aber es funktioniert eigentlich atm ganz gut =)

Danke euch.

Nur ne kurze andere Frage:
Ich habe bereits gegoogelt, aber nix brauchbares gefunden. Was ist die Standardhintergrundfarbe einer Swingkomponente? Ihr wisst schon, das hellgrau da.
 

Marco13

Top Contributor
Das hängt vom "Look and Feel" ab - d.h. ist unter Windows u.U. anders als unter Linux, und wenn man "Nimubs" einstellt anders als überall anders ;)

Man kann die einer bestimmten mit component.getBackground() bekommen, die allgemeine kann man evtl. irgendwo in den UIDefaults nachsehen...
 

andre111

Bekanntes Mitglied
Du kannst auch zuerst ein Bild erstellen, mit der Hintergrundfarbe (getBackground()) der Komponente füllen und dann die eigentliche Komponente (ob opak oder nicht) darauf zeichnen.

EDIT: Wobei das Probleme machen kann, wenn die Komponente die gezeichnet werden soll nicht opak ist und als Hintergrundfarbe z.B. blau hat und die Parent-Komponente das Standardgrau als Hintergrundfarbe hat, dann ist im Fenster als Hintergrundfarbe das Grau sichtbar, aber in dem gezeichneten Bild das Blau.
 
Zuletzt bearbeitet:

icarus2

Top Contributor
Also, es funktioniert jetzt alles wunderbar =)

Damit die JComponent wieder den Standardhintergrund bekommt mache ich jetzt einfach setBackground(null). Mit setOpaque(false) würde zwar den gewünschten Effekt auch erzielen, die JComponent darf aber wegen dem creageGraphics() nicht getOpaque() == false haben, da sonst der Hintergrund nicht grau, sondern schwarz ist.

Vielen Dank nochmal für eure tolle Hilfe.

Mfg ica
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
B Batik: Inhalt JComponent to SVG? AWT, Swing, JavaFX & SWT 6
Hatsi09 JComponent anklicken und "entklicken" AWT, Swing, JavaFX & SWT 7
L JComponent aus JPanel anhand Mausposition ermitteln AWT, Swing, JavaFX & SWT 10
S Swing Schwierigkeiten mit JComponent AWT, Swing, JavaFX & SWT 4
T Swing JComponent vergrößern AWT, Swing, JavaFX & SWT 4
L JComponent und MouseMotionListener AWT, Swing, JavaFX & SWT 2
M Mouse Click Event ohne ein JComponent Objekt AWT, Swing, JavaFX & SWT 3
L Eigene JComponent in GridLayout AWT, Swing, JavaFX & SWT 9
Z JComponent's requestFocus() - Wieso nicht immer anwendbar? AWT, Swing, JavaFX & SWT 1
Z Java-Swing : JComponent AWT, Swing, JavaFX & SWT 2
W JComponent - ComponentListener - resized / moved AWT, Swing, JavaFX & SWT 5
Developer_X Wie heißt das JComponent hier? AWT, Swing, JavaFX & SWT 2
A Swing Eigene JComponent Scrollable AWT, Swing, JavaFX & SWT 6
R JComponent auf Canvas AWT, Swing, JavaFX & SWT 8
A Abgeleitete JComponent wird nicht gezeichnet AWT, Swing, JavaFX & SWT 10
A JComponent Größe AWT, Swing, JavaFX & SWT 8
T jcomponent wird nicht angezeigt AWT, Swing, JavaFX & SWT 9
S Eigene JComponent Image zeichnen AWT, Swing, JavaFX & SWT 3
H Swing "Drag and Drop" eines JComponent über ein JPanel AWT, Swing, JavaFX & SWT 2
N 2D-Grafik RTF in eigener JComponent AWT, Swing, JavaFX & SWT 2
D Swing JComponent zeichnen ohne sie zur Oberfläche hinzuzufügen AWT, Swing, JavaFX & SWT 2
P JComponent / JLabel drehen (Rotation) AWT, Swing, JavaFX & SWT 2
D JComponent erweitern AWT, Swing, JavaFX & SWT 4
1 JComponent -> java.lang.NullPointerException AWT, Swing, JavaFX & SWT 13
M 2x JComponent in einem JFrame darstellen? AWT, Swing, JavaFX & SWT 7
StupidAttack Animation, JComponent AWT, Swing, JavaFX & SWT 3
P Swing Eigene Komponente Entwickeln - erben von JComponent oder JPanel? AWT, Swing, JavaFX & SWT 5
B Wechsel JTextArea und JComponent AWT, Swing, JavaFX & SWT 9
H JComponent == JTextfield? AWT, Swing, JavaFX & SWT 4
C Ermitteln ob JComponent einen Listener besitzt AWT, Swing, JavaFX & SWT 2
T Eigene JComponent AWT, Swing, JavaFX & SWT 4
G JComponent nachträglich in JPanel einfügen AWT, Swing, JavaFX & SWT 5
M Ganzen Frame mit JComponent ausfüllen AWT, Swing, JavaFX & SWT 9
M JMenu teilweise unter einer JComponent AWT, Swing, JavaFX & SWT 4
1 Eigene JComponent mit MouseListener versehen AWT, Swing, JavaFX & SWT 10
T JComponent nur in Swing verwendbar? AWT, Swing, JavaFX & SWT 6
M Mehrere Icons in einer JComponent AWT, Swing, JavaFX & SWT 5
Dragonfire Image von JComponent AWT, Swing, JavaFX & SWT 2
T x und y herrausfinden eines JComponent auf JFrame AWT, Swing, JavaFX & SWT 14
J absolute Position einer JComponent ermitteln AWT, Swing, JavaFX & SWT 4
B "weiches" Bewegen von einem JComponent AWT, Swing, JavaFX & SWT 18
ARadauer JPanel vs JComponent AWT, Swing, JavaFX & SWT 2
I JDialog aus JComponent erstellen AWT, Swing, JavaFX & SWT 2
S JComponent u. JPanel ausdrucken AWT, Swing, JavaFX & SWT 3
J SWT JComponent Problem AWT, Swing, JavaFX & SWT 4
T JComponent überzeichnen? AWT, Swing, JavaFX & SWT 2
G JComponent in JTable AWT, Swing, JavaFX & SWT 8
M JComponent wird in JFrame nicht angezeigt AWT, Swing, JavaFX & SWT 4
D bei Thread in JComponent malen NullPointerException AWT, Swing, JavaFX & SWT 3
S Alle EventListener einer JComponent abfragen? AWT, Swing, JavaFX & SWT 3
S JComponent in JPanel darstellen AWT, Swing, JavaFX & SWT 2
N JComponent#getClientProperty(key) welche Schlüssel gibt es? AWT, Swing, JavaFX & SWT 3
E Drucken von JComponent. AWT, Swing, JavaFX & SWT 4
S JComponent ersetzen AWT, Swing, JavaFX & SWT 13
R Resize Problem bei JComponent AWT, Swing, JavaFX & SWT 2
M JButton in JComponent abfragen AWT, Swing, JavaFX & SWT 6
S Mausbehandlungen für JComponent AWT, Swing, JavaFX & SWT 7
M Verschiebbare JComponent AWT, Swing, JavaFX & SWT 5
C zeichnen auf jComponent AWT, Swing, JavaFX & SWT 3
S in einem JComponent zu zeichnen AWT, Swing, JavaFX & SWT 4
G Grafik auf JComponent ohne Überschreiben von Paint-Methoden AWT, Swing, JavaFX & SWT 4
R JComponent malt seine Kinder nicht AWT, Swing, JavaFX & SWT 8
G JComponent Hintergrund AWT, Swing, JavaFX & SWT 3
M JMenu auf JComponent? AWT, Swing, JavaFX & SWT 10
G Graphics (g) und JComponent prob. AWT, Swing, JavaFX & SWT 2
G Klasse XYComponent extends JComponent AWT, Swing, JavaFX & SWT 3
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 JPanel Graphic2D als BufferedImage Speichern AWT, Swing, JavaFX & SWT 5
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
P BufferedImage auf JPanel AWT, Swing, JavaFX & SWT 11
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

Ähnliche Java Themen

Neue Themen


Oben