Question

Je suis en train de transformer un tableau de valeurs en pixels (créé à l'origine avec un objet java.awt.image.PixelGrabber) en objet Image à l'aide du code suivant:

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

Est-il possible d'obtenir le même résultat en utilisant les classes du ou des packages ImageIO sans avoir à utiliser AWT Toolkit?

Toolkit.getDefaultToolkit () ne semble pas fiable à 100% et génère parfois une erreur AWTError, alors que les classes ImageIO doivent toujours être disponibles, raison pour laquelle je souhaite modifier ma méthode.

Était-ce utile?

La solution

Vous pouvez créer une image sans utiliser ImageIO. Créez simplement une BufferedImage en utilisant un type d’image correspondant au contenu du tableau de pixels.

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

Lorsque vous utilisez PixelGrabber, n'oubliez pas d'extraire les informations RGBA du tableau de pixels avant d'appeler getImageFromArray . Vous en trouverez un exemple dans la handlepixelmethod dans le javadoc PixelGrabber. Cela fait, assurez-vous que le type d'image dans le constructeur BufferedImage est défini sur BufferedImage.TYPE_INT_ARGB .

Autres conseils

À l'aide du raster, j'ai obtenu une ArrayIndexOutOfBoundsException même lorsque j'ai créé BufferedImage avec TYPE_INT_ARGB . Cependant, l’utilisation de la méthode setRGB (...) de BufferedImage a fonctionné pour moi.

JavaDoc sur BufferedImage.getData () indique: "Un raster qui est une copie des données de l'image".

Ce code fonctionne pour moi, mais je doute de son efficacité:

        // Получаем картинку из массива.
        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);

J'ai réussi à utiliser java.awt.Robot pour capturer une capture d'écran (ou un segment de l'écran), mais pour utiliser ImageIO, vous devez le stocker dans une BufferedImage au lieu de l'image mémoire. la source. Ensuite, vous pouvez appeler une méthode statique d'ImageIO et enregistrer le fichier. Essayez quelque chose comme:

// 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);

Comme il s’agit de l’une des questions les plus votées avec ImageIO sur SO, je pense qu’il reste encore de la place pour une meilleure solution, même si la question est ancienne. : -)

Consultez le BufferedImageFactory.java de mon projet imageio open source sur GitHub.

Avec cela, vous pouvez simplement écrire:

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

L’autre avantage est que, dans le pire des cas, cette approche a à peu près les mêmes performances (temps) que les exemples basés sur PixelGrabber déjà dans ce fil de discussion. Dans la plupart des cas courants (généralement au format JPEG), le délai est environ deux fois plus rapide. Dans tous les cas, il utilise moins de mémoire.

En prime, le modèle de couleur et la disposition en pixels de l'image d'origine sont conservés au lieu d'être traduits en int ARGB avec le modèle de couleur par défaut. Cela pourrait économiser de la mémoire supplémentaire.

(PS: l’usine prend également en charge les écouteurs de sous-échantillonnage, de région d’intérêt et de progression si cela vous intéresse.: -)

J'ai eu le même problème que tout le monde essaye d'appliquer la bonne réponse à cette question. Mon tableau int obtient en fait une exception OutOfboundException où je l'ai corrigé en ajoutant un autre index car la longueur du tableau doit être widht * height * 3 après cela, je ne pouvais pas obtenir l'image, donc je l'ai corrigé en définissant la trame à l'image

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

Et vous pouvez voir l’image si vous la montrez sur une étiquette sur un jframe comme ceci

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

réglage de l'image sur imageIcon (). Dernier conseil, vous pouvez essayer de remplacer Bufferedimage.TYPE_INT_ARGB par quelque chose d’autre qui correspond à l’image que vous avez obtenue. Ce tableau est très important. J'avais un tableau de 0 et -1. J'ai donc utilisé ce type BufferedImage.TYPE_3BYTE_BGR

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top