BufferedImage - auf einzelne Pixel zugreifen
-
Hallo,
gibt es eine Möglichkeit bei einem BufferedImage direkt auf die Pixel lesend und schreibend zuzugreifen? Ich soll ein Bild mit einem Algorithmus bearbeiten und diese Bearbeitung durch Threads nun beschleunigen. Allerdings braucht 1 Thread bei mir weniger Zeit als zB 6 Threads, weswegen ich die Befürchtung habe, dass das BufferedImage bei set/getRGB die Zugriffe synchronisiert und die Threads sich dadurch gegenseitig ausbremsen. Über das WritableRaster komme ich zwar mit getPixels an ein int[] Array der Pixel, allerdings sind die Arrays bei großen Bildern viel zu speicherintensiv, da jeder Farbton einzeln als int hintereinanderliegt. getPixels in kleinere Arraybereiche aufzuteilen, würde generell funktionieren, allerdings baut jeder Zeile auf der vorhergehenden auf, weswegen ich beim nächsten Teilabschnitt warten müsste, bis er komplett berechnet wurde.
Nun also die Frage, wie komme ich unsynchronisiert an die Pixel des Bildes?
greetz KN4CK3R
-
bin mir nicht sicher ob ich das problem verstehe.
afaik hatte das bufferdimage doch sowas wie "getsubimage". meintest du das?
es würde da noch die "java advanced image api" JAI http://java.sun.com/products/java-media/jai/README-1_1_2_01.html
da gibt es eine tiledimage klasse
-
danke, aber ich hab mir mittlerweile selbst helfen können. getRGB(0,0,w,h,array,0,w); liefert mir die Pixel als kompaktes int[w*h]. Sowas hatte ich gesucht.
greetz KN4CK3R
-
KN4CK3R schrieb:
danke, aber ich hab mir mittlerweile selbst helfen können. getRGB(0,0,w,h,array,0,w); liefert mir die Pixel als kompaktes int[w*h]. Sowas hatte ich gesucht.
greetz KN4CK3R
Dir ist klar, dass das im Endeffekt dann mehr Speicher verbrauchen wird, als wenn jeder Thread auf das komplette Bild Array schreibt?
Falls du übrigens keine 6 Kerne in deinem PC hast kannst du davon ausgehen, dass 6 Threads immer langsamer sind als 1/2/4 Thread(s) die die selbe Aufgabe erledigen
-
KN4CK3R schrieb:
Über das WritableRaster komme ich zwar mit getPixels an ein int[] Array der Pixel, allerdings sind die Arrays bei großen Bildern viel zu speicherintensiv, da jeder Farbton einzeln als int hintereinanderliegt.
Hmmm. Über Bilder welcher Größe reden wir hier? Ich meine, ein Bild der Größe 1000x1000 passt als solch ein Array noch locker in den Cache eines heutigen Prozessors. Da musst Du also noch nichtmal auf den Arbeitsspeicher ausweichen.
Generell würde ich Dir empfehlen, falls Du ernsthaft mit Bildern arbeitest, dann arbeite direkt auf Arrays und nutze BufferedImage-Objekte nur für die Ein- und Ausgabe. Ich meine nicht, dass Du das Array nutzen sollst, das im BufferedImage drinsteckt, sondern, dass Du Dir einfach ein Array anlegen solltest, völlig unabhängig vom BufferedImage.
-
@gastantwort: natürlich hole ich nur einmal am Anfang das ganze Bild als Array und jeder Thread arbeitet auf diesem einen Array.
@Gregor: Testbild war 4000x4000 und die getPixels Methode des WritableRasters des BufferedImage benötigt ein Array der Größe 4000*4000*4 und soviel wollte mir die VM nicht geben ohne Anpassung der Startparameter.
greetz KN4CK3R