Frage

Ich bin derzeit ein Array von Pixelwerten Drehen in ein Bildobjekt mit dem folgenden Code (ursprünglich mit einem java.awt.image.PixelGrabber Objekt erstellt):

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, das gleiche Ergebnis mit Klassen aus dem ImageIO Paket (e) zu erreichen, so dass ich nicht über den AWT-Toolkit verwenden?

Toolkit.getDefaultToolkit () scheint nicht 100% zuverlässig zu sein und wird manchmal ein AWTError werfen, während die ImageIO Klassen immer verfügbar sein sollten, weshalb ist, ich bin interessiert meine Methode zu ändern.

War es hilfreich?

Lösung

Sie können das Bild erstellen, ohne ImageIO zu verwenden. Erstellen nur eines BufferedImage einen Bildtyp unter Verwendung des Inhalts des Pixelarrays entsprechen.

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;
        }

Wenn Sie mit dem PixelGrabber arbeitet, nicht zu vergessen die RGBA Informationen aus dem Pixelfeld zu extrahieren, bevor getImageFromArray Aufruf. Es ist ein Beispiel dafür in der handlepixelmethod im PixelGrabber javadoc. Sobald Sie das tun, stellen Sie sicher, dass der Bildtyp in der BufferedImage Konstruktor BufferedImage.TYPE_INT_ARGB.

Andere Tipps

Mit dem Raster ich eine ArrayIndexOutOfBoundsException bekam, auch wenn ich die BufferedImage mit TYPE_INT_ARGB erstellt. Doch für mich mit der setRGB(...) Methode von BufferedImage gearbeitet.

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

Dieser Code funktioniert für mich, aber ich bezweifle, in seiner 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);

ich gute Erfolge mit java.awt.Robot hatte einen Screenshot (oder ein Segment des Bildschirms) zu packen, aber mit ImageIO zu arbeiten, müssen Sie es in einem BufferedImage anstelle des Speicherbild zu speichern, Quelle. Dann können Sie eine statische Methode ImageIO aufrufen und die Datei speichern. Versuchen Sie so 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);

Da dies eine der höchsten gestimmt Frage mit ImageIO auf SO markiert ist, ich glaube, es gibt noch Raum für eine bessere Lösung, auch wenn die Frage alt ist. : -)

Haben Sie einen Blick auf die BufferedImageFactory.java Klasse von meinem Open-Source-Projekt ImageIO auf GitHub.

Mit ihm können Sie einfach schreiben:

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

Die andere gute Sache ist, dass dieser Ansatz als schlimmster Fall hat etwa die gleiche Leistung (Zeit) als die PixelGrabber-basierten Beispiele bereits in diesem Thread. Für die meisten der häufigsten Fälle (in der Regel JPEG), ist es etwa doppelt so schnell. Auf jeden Fall braucht es weniger Speicher.

Als Neben Bonus wird das Farbmodell und Pixel Layout des Originalbildes gehalten, statt übersetzt ARGB mit Standard-Farbmodell in int. Dies könnte zusätzlichen Speicher speichern.

(PS: Die Fabrik unterstützt auch Subsampling, Region-of-Interest und Fortschritt Zuhörer, wenn jemand interessiert: -).

Ich hatte das gleiche Problem von allen anderen die richtige Antwort auf diese Frage anzuwenden versuchen, eigentlich mein int Array eine OutOfboundException bekommen, wo ich es noch Index fixiert Zugabe, da die Länge des Arrays werden Widht hat * Höhe * 3 danach konnte ich das Bild nicht bekommen, so dass ich es die Einstellung der Raster auf das Bild fixiert

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);
        image.setData(raster); 
        return image;
    }

Und Sie können das Bild sehen, wenn u es auf einem Etikett auf einem JFrame wie diese zeigen

    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(new FlowLayout());
    frame.getContentPane().add(new JLabel(new ImageIcon(image)));
    frame.pack();
    frame.setVisible(true);

Einstellen des Bildes auf dem ImageIcon (). Letzter Rat können Sie versuchen, die Bufferedimage.TYPE_INT_ARGB auf etwas anderes, das das Bild, das Sie von dieser Art die Anordnung bekamen paßt zu ändern ist sehr wichtig i eine Reihe von 0 hatte und -1, so habe ich diese Art BufferedImage.TYPE_3BYTE_BGR

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top