Ich suche nach dem schnellsten Weg, um Pixeldaten (im Formular int[][]
) von a zu erhalten BufferedImage
. Mein Ziel ist es, Pixel (x, y)
aus dem Bild mit zu adressieren int[x][y]
. Alle Methoden, die ich gefunden habe, tun dies nicht (die meisten geben int[]
s zurück).
java
bufferedimage
javax.imageio
Ryyst
quelle
quelle
getRGB
undsetRGB
direkt?getRGB
undsetRGB
direkt.Antworten:
Ich habe nur mit demselben Thema herumgespielt, was der schnellste Weg ist, auf die Pixel zuzugreifen. Ich kenne derzeit zwei Möglichkeiten, dies zu tun:
getRGB()
Methode von BufferedImage, wie in der Antwort von @ tskuzzy beschrieben.Durch direkten Zugriff auf das Pixel-Array mit:
Wenn Sie mit großen Bildern arbeiten und die Leistung ein Problem darstellt, ist die erste Methode absolut nicht der richtige Weg. Die
getRGB()
Methode kombiniert die Werte für Alpha, Rot, Grün und Blau zu einem Int und gibt dann das Ergebnis zurück. In den meisten Fällen gehen Sie umgekehrt vor, um diese Werte zurückzugewinnen.Die zweite Methode gibt die Rot-, Grün- und Blauwerte direkt für jedes Pixel zurück. Wenn ein Alphakanal vorhanden ist, wird der Alphawert addiert. Die Verwendung dieser Methode ist bei der Berechnung von Indizes schwieriger, jedoch viel schneller als der erste Ansatz.
In meiner Anwendung konnte ich die Verarbeitungszeit der Pixel um mehr als 90% reduzieren, indem ich einfach vom ersten zum zweiten Ansatz wechselte!
Hier ist ein Vergleich, den ich eingerichtet habe, um die beiden Ansätze zu vergleichen:
Können Sie die Ausgabe erraten? ;)
quelle
convertTo2DUsingGetRGB
undconvertTo2DWithoutUsingGetRGB
. Der erste Test dauert durchschnittlich 16 Sekunden. Der zweite Test dauert durchschnittlich 1,5 Sekunden. Zuerst dachte ich, dass "s" und "ms" zwei verschiedene Spalten sind. @ Mota, tolle Referenz.BufferedImage
‚s zumtype
BeispielTYPE_INT_RGB
oder inTYPE_3BYTE_BGR
geeigneter Weise und Griff. Dies ist eines der Dinge , diegetRGB()
für Sie tut, dass es langsamer macht :-(|=
anstatt sie+=
zu kombinieren?Etwas wie das?
quelle
BufferedImage
die Pixel trotzdem mit einem 2D-Int-Array gespeichert?Raster
Datenpuffer des Datenpuffers zugreift , was definitiv eine gute Sache ist, da dies zu einem Beschleunigungs-Punting führt.Ich fand, dass Motas Antwort mir eine 10-fache Geschwindigkeitssteigerung bescherte - also danke Mota.
Ich habe den Code in eine praktische Klasse eingepackt, die das BufferedImage im Konstruktor verwendet und eine äquivalente getRBG (x, y) -Methode verfügbar macht, wodurch der Code mithilfe von BufferedImage.getRGB (x, y) ersetzt wird.
quelle
Motas Antwort ist großartig, es sei denn, Ihr BufferedImage stammt von einer monochromen Bitmap. Eine monochrome Bitmap hat nur 2 mögliche Werte für ihre Pixel (zum Beispiel 0 = Schwarz und 1 = Weiß). Wenn eine monochrome Bitmap verwendet wird, wird die
call gibt die rohen Pixel-Array-Daten so zurück, dass jedes Byte mehr als ein Pixel enthält.
Wenn Sie also ein monochromes Bitmap-Bild zum Erstellen Ihres BufferedImage-Objekts verwenden, ist dies der Algorithmus, den Sie verwenden möchten:
quelle
Wenn dies nützlich ist, versuchen Sie Folgendes:
quelle
Hier ist eine weitere FastRGB Implementierung gefunden hier :
Was ist das?
Das pixelweise Lesen eines Bildes mit der getRGB-Methode von BufferedImage ist recht langsam. Diese Klasse ist die Lösung dafür.
Die Idee ist, dass Sie das Objekt erstellen, indem Sie ihm eine BufferedImage-Instanz zuführen. Dabei werden alle Daten gleichzeitig gelesen und in einem Array gespeichert. Sobald Sie Pixel erhalten möchten, rufen Sie getRGB auf
Abhängigkeiten
Überlegungen
Obwohl FastRGB das Lesen von Pixeln erheblich beschleunigt, kann dies zu einer hohen Speichernutzung führen, da lediglich eine Kopie des Bildes gespeichert wird. Wenn Sie also ein 4MB BufferedImage im Speicher haben, beträgt die Speichernutzung nach dem Erstellen der FastRGB-Instanz 8 MB. Sie können die BufferedImage-Instanz jedoch nach dem Erstellen des FastRGB wiederverwenden.
Achten Sie darauf, dass Sie nicht in OutOfMemoryException fallen, wenn Sie es auf Geräten wie Android-Telefonen verwenden, bei denen RAM ein Engpass ist
quelle
Das hat bei mir funktioniert:
quelle
i
?