BufferedImage-Fehler? Falsches Bild wir gezeichnet

  • Themenstarter Themenstarter Conehead
  • Beginndatum Beginndatum
C

Conehead

Gast
Hallo.
Ich weiß nicht ganz, wie ich diesen Thread hier nennen soll, daher versuch ich einfach mal kurz zu erklären was ich vorhabe.
Ich habe 2 Panels untereinander. Oben soll ein Bild angezeigt werden, welches ich von der Webcam abgreife.
Darunter möchte ich das selbe Panel haben, nur dass noch etwas extra auf das Bild gezeichnet wird.
(Habe einfach ein paar rosa Punkte ins Bild gemalt)

Mein Problem liegt jetzt daran, dass wenn ich das Bild bearbeite, jedoch beide Bilder bearbeitet wurden.
Also sind meine Punkte im Panel oben und unten, obwohl sie nur unten sein sollten.

Hier mal ein kleine Bild dazu:
unbenanntqsy.jpg


Hier noch etwas Quelltext:

Java:
public void getScreenshotFromCam(Gui gui) {
                //aktuelles bild von der cam holen
		ScreenPanel imgpanel = gui.getCurrentScreenPanel();
		Player player = gui.getActiveCam();
		if(player != null){
		FrameGrabbingControl fgc = (FrameGrabbingControl) player
				.getControl("javax.media.control.FrameGrabbingControl");
                //im buffer speichern und in Image konvertieren
		buf = fgc.grabFrame();
		btoi = new BufferToImage((VideoFormat) buf.getFormat());
		createdImage = btoi.createImage(buf);
                //oberen panel bild hinzufügen
		imgpanel.setImage(createdImage);
                //bild an funktion für unteres panel weitergeben
		convertImageToMap(gui,createdImage);
		}
	}
	
	public void convertImageToMap(Gui gui, Image srcImg){
                //unteres panel auslesen
		ScreenPanel imgpanel2 = gui.getCurrentSolutionPanel();
               //als bufferedimage 
		BufferedImage img = (BufferedImage) srcImg;
                //punkte zeichnen
		img.setRGB(30, 30,16711780);
		img.setRGB(31, 31,16711780);
		img.setRGB(32, 32,16711780);
		img.setRGB(33, 33,16711780);
                //das bild zum schluss zeichnen
		imgpanel2.setImage(img);
	}

Das komisch ist ja, dass ich am Ende der ersten Funktion folgendes aufrufe:

imgpanel.setImage(createdImage);
convertImageToMap(gui,createdImage);

Also wird dem Panel auf dem das Bild gezeichnet werden soll, erst das Bild übergeben...und erst DANN wird das Bild übergeben und bearbeitet und neu gespeichert.

Hoffe ihr könnt mir helfen, ich bin so langsam am Verzweifeln und vorher möchte ich auch noch nicht weiterarbeiten.

MfG

conehead
 
Ähmja... kann sein dass da irgendwo dasselbe Bild verwendet wird, wo nicht dasselbe verwendet werden sollte... kannst man sowas testen wie
Java:
public void convertImageToMap(Gui gui, Image srcImg){
                //unteres panel auslesen
        ScreenPanel imgpanel2 = gui.getCurrentSolutionPanel();
               //als bufferedimage 
        BufferedImage imgIn = (BufferedImage) srcImg;
      

        // Neues Bild erzeugen, in das das alte reingemalt wird....
        BufferedImage img = new BufferedImage(imgIn.getWidth(), imgIn.getHeight(), BufferedImage.TYPE_INT_RGB);
        img.getGraphics().drawImage(imgIn,0,0,null);
                //punkte zeichnen
        img.setRGB(30, 30,16711780);
        img.setRGB(31, 31,16711780);
        img.setRGB(32, 32,16711780);
        img.setRGB(33, 33,16711780);
                //das bild zum schluss zeichnen
        imgpanel2.setImage(img);
    }

Das könnte man ggf. eleganter machen... und sollte man vielleicht auch ... aber schau erstmal ob das passt...
 
Wow.
Ja das funktioniert!
Vielen Dank.

Hatte auch schon so etwas überlegt, aber habe mir dann eigentlich doch gedacht, dass es das ja nicht sein kann,
da ich doch das Bild bereits vorher auf das obere Panel lege!
 
Das könnte man ggf. eleganter machen...

Finde ich ziemlich elegant, quick & dirty gelöst - ganz nach Daniel Düsentrieb-Manier 😀

Würde selbst aber bei nächster Gelegenheit den Fehler suchen.
Sieht nach ner übergebenen Referenz statt ner echten Kopie aus.

edit: mein ich mal, so als fast-hoffentlich-bald-nicht-mehr-anfänger
 
Zuletzt bearbeitet:
Ja, ist es wohl auch: [EDIT: Nein, elegant ist es nicht 😳 Ich meinte die Ursache:] Bei
imgpanel.setImage(createdImage);
wird eine Referenz übergeben. Diese Referenz wird dann weitergereicht, und weiter unten wurde mit
imgpanel2.setImage(img);
eine andere Referenz aber eben auf dasSELBE Bild an das andere Panel üebrgeben.

Am günstigsten wäre wohl, EINmal an einem geeigneten Platz ein Bild zu erstellen, in dem man die Bearbeitungen machen will. Ich habe selbst noch nicht mit FrameGrabbingControl usw. gearbeitet, aber offenbar bekommt man dan ja immer ein neues Bild?! Aber vermutlich immer mit der gleichen Größe. Man könnte sowas machen wie
Code:
private BufferedImage editImage = null;

public void holsVonDerCam()
{
    Image image = frageGrabberUndSo.convertImage();
    putImageToMap(image);
}

private void putImageToMap(Image image)
{
     // Nur EINmal ein neues Bild erstellen, wenn es noch keins gibt
    if (editImage == null)
    {
        editImage = new BufferedImage(...);
    }

     // Das übergebene Bild in das EditImage reinmalen:
     editImage.getGraphics().drawImage(image,0,0,null);

    ....

}

Dass das casten auf BufferedImage klappt, ist vermutlich nämlich auch eher Glücksache 😀
 
Ich finde es gar nicht mal so unelegant, denn letztendlich erzeugst Du durch das Hineinzeichen gewissermassen ja doch eine echte Kopie. Ich sehe da noch nicht mal die Gefahr von Nebenwirkungen, ausser vielleicht, dass es performantere Lösungen gibt...

Da ich jetzt aber die dritte Nacht hintereinander besch...eiden geschlafen habe und kurz davor bin, zu haluzinieren, sehe ich mich gerade nicht in der Lage, die source zu verstehen, ist aktuell nicht mein Stoff 😉

edit: nu isses etwas dudengerechter 🙂
 

Zurück
Oben