我正在使用以下代码将像素值数组(最初使用java.awt.image.PixelGrabber对象创建)转换为Image对象:
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);
}
是否可以使用ImageIO软件包中的类实现相同的结果,因此我不必使用AWT工具包?
Toolkit.getDefaultToolkit()似乎不是100%可靠,有时会抛出一个AWTError,而ImageIO类应该始终可用,这就是为什么我有兴趣改变我的方法。
答案 0 :(得分:27)
您可以在不使用ImageIO的情况下创建图像。只需使用与像素数组内容匹配的图像类型创建BufferedImage。
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;
}
使用PixelGrabber时,不要忘记在调用getImageFromArray
之前从像素阵列中提取RGBA信息。在PixelGrabber javadoc的handlepixelmethod中有一个例子。完成后,请确保BufferedImage构造函数中的图像类型为BufferedImage.TYPE_INT_ARGB
。
答案 1 :(得分:7)
使用栅格即使我使用ArrayIndexOutOfBoundsException
创建BufferedImage
,我也获得了TYPE_INT_ARGB
。但是,使用setRGB(...)
BufferedImage
方法为我工作。
答案 2 :(得分:3)
BufferedImage.getData()上的JavaDoc说:“一个栅格,它是图像数据的复制。”
这段代码对我有用,但我怀疑它的效率:
// Получаем картинку из массива.
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 :(得分:2)
我使用java.awt.Robot获取屏幕截图(或屏幕的一部分)取得了很好的成功,但要使用ImageIO,您需要将其存储在BufferedImage而不是内存映像中资源。然后,您可以调用ImageIO的一个静态方法并保存该文件。尝试类似:
// 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);
答案 4 :(得分:0)
由于这是在SO上用ImageIO标记的最高投票问题之一,我认为即使问题很老,仍然有更好的解决方案。 : - )
从我在GitHub的开源imageio项目中查看BufferedImageFactory.java类。
有了它,你可以简单地写:
BufferedImage image = new BufferedImageFactory(image).getBufferedImage();
另一个好处是,作为最坏的情况,这种方法与此线程中已经基于PixelGrabber
的示例具有大致相同的性能(时间)。对于大多数常见情况(通常是JPEG),它的速度大约是其两倍。无论如何,它使用更少的内存。
作为副作用,保留原始图像的颜色模型和像素布局,而不是使用默认颜色模型转换为int ARGB。这可能会节省额外的内存。
(PS:如果有人感兴趣,工厂还支持子采样,感兴趣区域和进度监听器。: - )
答案 5 :(得分:-1)
我有同样的问题,其他人试图应用这个问题的正确答案,我的int数组实际上得到一个OutOfboundException我修复它添加一个索引因为数组的长度必须是widht * height * 3在此之后我无法获得图像所以我修复了它将光栅设置为图像
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
如果你把它显示在像这样的jframe上的标签上,你可以看到图像
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;
}
在imageIcon()上设置图像。 最后的建议你可以尝试将Bufferedimage.TYPE_INT_ARGB改为与你从这种类型获得数组的图像匹配的其他东西是非常重要的,我有一个0和-1的数组,所以我使用了这个类型BufferedImage.TYPE_3BYTE_BGR