28

我目前正在使用以下代码将像素值数组(最初使用 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 类应该始终可用,这就是我对更改方法感兴趣的原因。

4

6 回答 6

29

您可以在不使用 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. 在 PixelGrabber javadoc的handlepixelmethod中有一个例子。完成此操作后,请确保 BufferedImage 构造函数中的图像类型为BufferedImage.TYPE_INT_ARGB.

于 2008-09-24T02:08:37.950 回答
7

使用栅格,我在创建withArrayIndexOutOfBoundsException时得到了一个偶数。但是,使用为我工作的方法。BufferedImageTYPE_INT_ARGBsetRGB(...)BufferedImage

于 2009-04-29T22:53:05.773 回答
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);
于 2011-02-03T10:14:57.637 回答
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);
于 2008-09-24T01:51:30.037 回答
0

由于这是在 SO 上用 ImageIO 标记的投票率最高的问题之一,我认为即使问题已经过时,仍然有更好的解决方案的空间。:-)

查看我在 GitHub 上的开源 imageio 项目中的BufferedImageFactory.java类。

有了它,你可以简单地写:

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

另一个好处是,作为最坏的情况,这种方法的性能(时间)与PixelGrabber该线程中已经基于 - 的示例具有大致相同的性能(时间)。对于大多数常见情况(通常是 JPEG),它的速度大约是原来的两倍。无论如何,它使用更少的内存。

作为附带奖励,原始图像的颜色模型和像素布局被保留,而不是使用默认颜色模型转换为 int ARGB。这可能会节省额外的内存。

(PS:如果有人感兴趣,工厂还支持子采样、感兴趣区域和进度侦听器。:-)

于 2013-06-04T20:09:12.830 回答
0

我有同样的问题,其他人都试图应用这个问题的正确答案,我的 int 数组实际上得到了一个 OutOfboundException 我修复了它添加了一个索引,因为数组的长度必须是 widht*height*3 在这之后我无法获取图像,所以我修复了它,将光栅设置为图像

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

如果你像这样在 jframe 上的标签上显示它,你可以看到图像

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

在 imageIcon() 上设置图像。最后一条建议您可以尝试将 Bufferedimage.TYPE_INT_ARGB 更改为与您从该类型获得的数组匹配的图像非常重要我有一个 0 和 -1 的数组所以我使用了这种类型 BufferedImage.TYPE_3BYTE_BGR

于 2016-06-21T15:21:03.130 回答