Transformer un tableau de pixels dans une Image de l'objet avec Java ImageIO?
Je suis en train de tourner un tableau de valeurs de pixel (créé à l'origine avec un java.awt.image.PixelGrabber objet) dans une Image de l'objet en utilisant le 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 à l'aide de classes à partir de la ImageIO paquet(s) donc je n'ai pas à utiliser la boîte à outils AWT?
Toolkit.getDefaultToolkit() ne semble pas être fiable à 100% et parfois de jeter un AWTError, alors que la ImageIO classes devraient toujours être disponibles, c'est pourquoi je me suis intéressé à changer ma méthode.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez créer l'image sans l'aide de ImageIO. Il suffit de créer un BufferedImage à l'aide d'un type d'image correspondant au contenu de la gamme de pixels.
Lorsque vous travaillez avec le PixelGrabber, n'oubliez pas d'extraire le RGBA info à partir de la gamme de pixels avant d'appeler
getImageFromArray
. Il y a un exemple dans le handlepixelmethod dans le PixelGrabber javadoc. Une fois que vous faites cela, assurez-vous que le type d'image à la BufferedImage constructeur deBufferedImage.TYPE_INT_ARGB
.BufferedImage.getData()
renvoie uneRaster
etBufferedImage.getRaster()
renvoie uneWritableRaster
. Donc, si vous utilisezgetData()
semble qu'il renvoie une copie et aprèssetPixels()
vous devez le remettre à l'aide deBufferedImage.setData()
qui est une surcharge. Donc, il est préférable de l'utilisergetRaster()
et de travailler avec elle.À l'aide de la trame, j'ai eu une
ArrayIndexOutOfBoundsException
même quand j'ai créé leBufferedImage
avecTYPE_INT_ARGB
. Cependant, l'utilisation de lasetRGB(...)
méthode deBufferedImage
a fonctionné pour moi.JavaDoc sur BufferedImage.getData() dit: "un Raster qui est un copie de données de l'image."
Ce code fonctionne pour moi mais je doute de son efficacité:
getRaster()
au lieu degetData()
.J'ai eu un bon succès à l'aide de java.awt.Robot pour prendre une capture d'écran (ou un segment de l'écran), mais de travailler avec ImageIO, vous aurez besoin de le stocker dans un BufferedImage au lieu de la mémoire source de l'image. Ensuite, vous pouvez appeler une méthode statique de ImageIO et enregistrez le fichier. Essayez quelque chose comme:
Que c'est l'un des plus élevés voté question taggés avec ImageIO, et je pense qu'il y a encore de la place pour une meilleure solution, même si la question est ancienne. 🙂
Ont un look à la BufferedImageFactory.java classe de mon open source imageio projet sur GitHub.
Avec elle, vous pouvez simplement écrire:
L'autre bonne chose est que cette approche, en tant que pire des cas, a à peu près la même performance (temps) comme le
PixelGrabber
basée sur des exemples déjà dans ce fil. Pour la plupart des cas (généralement JPEG), il est environ deux fois plus vite. Dans tous les cas, il utilise moins de mémoire.Que d'un côté bonus, le modèle de couleur des pixels et de la mise en page de l'image d'origine est conservé, au lieu de convertis en int ARGB avec la couleur par défaut du modèle. Cela peut économiser de la mémoire supplémentaire.
(PS: L'usine prend également en charge le sous-échantillonnage, de la région d'intérêt et les progrès des auditeurs si ça intéresse quelqu'un. 🙂
J'ai eu le même problème tout le monde en essayant d'appliquer la bonne réponse à cette question, mon tableau int réellement obtenir un OutOfboundException où je fixe l'ajout d'un indice parce que la longueur du tableau doit être de largeur*hauteur*3 après cela, je ne pouvais pas obtenir l'image donc je fixe le réglage de la trame de l'image
Et vous pouvez voir l'image si u afficher sur une étiquette sur une jframe comme ce
réglage de l'image sur le imageIcon().
Dernier conseil, vous pouvez essayer de changer le Bufferedimage.TYPE_INT_ARGB à quelque chose d'autre qui correspond à l'image que vous avez obtenu le tableau de ce type est très important, j'ai eu un tableau de 0 et -1 donc j'ai utilisé ce type de BufferedImage.TYPE_3BYTE_BGR