bufferedImage darstellen

hallo!
ich lese einen film (.mov) ein und lese die einzelnen frames heraus und wandle sie in bufferedImages um! jetzt mein problem!
ich habe einen timer programmiert der je nach dem wie viele bilder pro sekunde das video hat, die bilder ausliest in bufferedImages speichert und zur zeit in einem Label wiedergibt!

so leider ist das sehr langsam dass ich bei einem video mit 25 fps max 15 fps schaffe! kann mir wer weiterhelfen wie ich an performance gewinne? es geht ums anzeigen… es ist klar dass ich keine 25 fps schaffe da das auslesen der frames auch bisschen was in anspruch nimmt… also ich lese aus und gebe aus solange bis film zu ende ist, die bilder werden nicht gespeichert, einfach wieder verworfen und das nächste wird ausgelesen!

bitte um hilfe…

danke & mfg
michael

Moien

ich habe einen timer programmiert der je nach dem wie viele
bilder pro sekunde das video hat, die bilder ausliest in
bufferedImages speichert und zur zeit in einem Label
wiedergibt!

Per JLabel.setIcon (new ImageIcon (…)) ? Ja, das ist langsam.

kann mir wer weiterhelfen wie ich an
performance gewinne?

Mal angenommen „anzeige“ ist das JLabel. Dann sollte dein Timer jedes Bild diesem Code anzeigen:

Graphics2D g = (Graphics2D) anzeige.getGraphics();
g.drawImage(buf, null, 0, 0);

(kein repaint!). Sauberer wäre es Canvas anstelle von JLabel zu benutzen.

cu

Ich fürchte da kannst du nicht mehr viel optimieren.
Ich habe einmal einen Sprite-Zeichnen-Test durchgeführt und war sehr enttäuscht. Bei 1024x786 hatte ich ca. 15 fps. Also total unzureichend, da meistens mehrere Layer, Audio, AI, etc. dazukommen und dadurch die Framerate noch weiter sinkt.
Die meisten Flashplayer verwenden wohl eine ähnliche Technik wie du. Zumindest ruckeln bei mir sehr viele Videos.
Um Videos wiederzugeben solltest du ein fertiges Framework verwenden. Geht wesentlich schneller und du musst dich nicht auch noch um andere Probleme wie Audio-Sync, etc. kümmern.

lg
Georg

Moien

Mal angenommen „anzeige“ ist das JLabel. Dann sollte dein
Timer jedes Bild diesem Code anzeigen:

Graphics2D g = (Graphics2D) anzeige.getGraphics();
g.drawImage(buf, null, 0, 0);

(kein repaint!). Sauberer wäre es Canvas anstelle von JLabel
zu benutzen.

cu

ah, das is ja spitze, an das hab ich noch gar nicht gedacht mir die graphics vom label zu holen, wird aber sicher nur um 2-3 frames pro sekunde schneller sein fürchte ich. werde es gleich ausprobieren und dann hier posten wies lief :smile: sollte auf jeden fall schneller sein als label.setIcon :o)

Moien

ah, das is ja spitze, an das hab ich noch gar nicht gedacht
mir die graphics vom label zu holen, wird aber sicher nur um
2-3 frames pro sekunde schneller sein fürchte ich.

Es hängt von der Platform und den BufferedImages ab. Eine BufferedImage speichert das Bild in einem bestimmten Code (RGB, BGR, RGBA,…). Beim malen muss dieser Code in den Code des OS gewandelt werden. Das ist der eigentliche Performancekiller. Die Wandelung kann man im Vorraus machen (Stichwort MediaTracker).

Der zweite Engpass ist der Transfer vom Hauptspeicher auf die Graka. Dafür kann man VolatileImage einsetzten.

AWT ist für sowas schneller als swing. Bei swing muss alles nach dem java-internen Zeichnen nachmal per bitblt an das OS geschoben werden. Bei AWT ist das nicht der Fall, da macht Graphics das bitblt mehr oder weniger selbst. Wenn du bei swing bleiben möchtest dann schalt wenigstens das DoubleBuffering für das Anzeigeelement ab.

Kombiniert man all diese Ansätze komm ich auf meinem 1.6GHz Testrechner deutlich über 100Hz Anzeigefrequenz (künstlich begrenzt per Timer weil es keinen Sinn macht mehr rauszujagen) und hab noch Zeit über um Daten im Hintergund zu verarbeiten. Da du nur ~25Hz brauchst…

cu

habe es so probiert, aber das bild wird nicht im JLabel angezeigt… ich mach das so…
zBuffer = video_label.getGraphics();

zBuffer.setColor©;
zBuffer.setFont(new Font(selectedFont, fontStyle, fontGroesse));

zBuffer.drawImage(image, 0, 0, null);//Frame

wie wird das im video_label angezeigt, oder wie meinst du? versteh das irgendwie nicht…

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moien

habe es so probiert, aber das bild wird nicht im JLabel
angezeigt… ich mach das so…
zBuffer = video_label.getGraphics();

zBuffer.setColor©;
zBuffer.setFont(new Font(selectedFont, fontStyle,
fontGroesse));

zBuffer.drawImage(image, 0, 0, null);//Frame

Du rufst die Methode „drawImage(Image img, int x, int y, ImageObserver observer)“ auf. Ich rede von „drawImage(BufferedImage img, BufferedImageOp op, int x, int y)“. Das ist eine ganz andere Baustelle. Die 2. Methode findet sich in Graphics2D (ab 1.4 kann man eigentlich alle swing und AWT Graphics-Objekte nach Graphics2D casten).

Deine Methode funktioniert nur wenn das Bild schon in der richtigen Codierung vorliegt. Die andere macht das Umcodieren notfalls selbst.

Und mach mal zBuffer.drawLine (0,0,1000,1000) um zu sehen wo das Bild rauskommen sollte.

cu