it-swarm.com.de

Ein Array von Pixeln mit Javas ImageIO in ein Image-Objekt verwandeln?

Ich verwandle derzeit ein Array von Pixelwerten (ursprünglich mit einem Java.awt.image.PixelGrabber-Objekt erstellt) in ein Image-Objekt mit dem folgenden Code:

public Image getImageFromArray(int[] pixels, int width, int height) {
    MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width);
    Toolkit tk = Toolkit.getDefaultToolkit();
    return tk.createImage(mis);
}

Ist es möglich, dasselbe Ergebnis mit Klassen aus den ImageIO-Paketen zu erzielen, sodass ich das AWT-Toolkit nicht verwenden muss?

Toolkit.getDefaultToolkit () scheint nicht 100% zuverlässig zu sein und löst manchmal einen AWTError aus, wohingegen die ImageIO-Klassen immer verfügbar sein sollten, weshalb ich daran interessiert bin, meine Methode zu ändern.

26

Sie können das Bild ohne ImageIO erstellen. Erstellen Sie einfach ein BufferedImage mit einem Bildtyp, der mit dem Inhalt des Pixelarrays übereinstimmt.

public static Image getImageFromArray(int[] pixels, int width, int height) {
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            WritableRaster raster = (WritableRaster) image.getData();
            raster.setPixels(0,0,width,height,pixels);
            return image;
        }

Vergessen Sie bei der Arbeit mit dem PixelGrabber nicht, die RGBA-Informationen aus dem Pixelarray zu extrahieren, bevor Sie getImageFromArray aufrufen. Ein Beispiel dafür gibt es in der handlepixelmethod im PixelGrabber Javadoc. Stellen Sie anschließend sicher, dass der Image-Typ im BufferedImage-Konstruktor auf BufferedImage.TYPE_INT_ARGB steht. 

27
Brendan Cashman

Mit dem Raster habe ich eine ArrayIndexOutOfBoundsException erhalten, auch wenn ich die BufferedImage mit TYPE_INT_ARGB erstellt habe. Die setRGB(...)-Methode von BufferedImage hat sich jedoch für mich bewährt.

7
mdm

JavaDoc in BufferedImage.getData () sagt: "ein Raster, das eine Kopie der Bilddaten ist."

Dieser Code funktioniert für mich, aber ich bezweifle die Effizienz:

        // Получаем картинку из массива.
        int[] pixels = new int[width*height];
            // Рисуем диагональ.
            for (int j = 0; j < height; j++) {
                for (int i = 0; i < width; i++) {
                    if (i == j) {
                        pixels[j*width + i] = Color.RED.getRGB();
                    }
                    else {
                        pixels[j*width + i] = Color.BLUE.getRGB();
                        //pixels[j*width + i] = 0x00000000;
                    }
                }
            }

BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
    pixelImage.setRGB(0, 0, width, height, pixels, 0, width);
3
beemaster

Ich habe mit Java.awt.Robot gute Erfolge erzielt, um einen Screenshot (oder ein Segment des Bildschirms) zu erstellen, aber um mit ImageIO arbeiten zu können, müssen Sie es in einem BufferedImage-Speicher statt der Speicher-Image-Quelle speichern. Dann können Sie eine statische Methode von ImageIO aufrufen und die Datei speichern. Versuchen Sie etwas wie:

// Capture whole screen
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capturedImage = new Robot().createScreenCapture(region);

// Save as PNG
File imageFile = new File("capturedImage.png");
ImageIO.write(capturedImage, "png", imageFile);
2
Steve Moyer

Da dies eine der am besten bewerteten Fragen ist, die mit ImageIO zu SO getaggt wurden, gibt es meiner Meinung nach noch Raum für eine bessere Lösung, selbst wenn die Frage alt ist. :-)

Schauen Sie sich die BufferedImageFactory.Java -Klasse aus meinem Open Source-Imageio-Projekt bei GitHub an. 

Mit ihm können Sie einfach schreiben: 

BufferedImage image = new BufferedImageFactory(image).getBufferedImage();

Die andere gute Sache ist, dass dieser Ansatz im schlimmsten Fall ungefähr dieselbe Leistung (Zeit) aufweist wie die PixelGrabber- basierten Beispiele, die bereits in diesem Thread enthalten sind. In den meisten Fällen (in der Regel JPEG) ist dies etwa doppelt so schnell. In jedem Fall wird weniger Speicher benötigt.

Als Nebenbonus wird das Farbmodell und das Pixel-Layout des Originalbilds beibehalten, anstatt es in Standard-ARGB mit Standardfarbmodell zu übersetzen. Dies kann zusätzlichen Speicherplatz sparen.

(PS: Die Fabrik unterstützt auch Subsampling-, Region-of-Interest- und Fortschrittslistener, wenn jemand interessiert ist. :-)

0
haraldK