我正在使用以下代码将像素值数组(最初使用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类应该始终可用,这就是为什么我有兴趣改变我的方法。

有帮助吗?

解决方案

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

其他提示

使用栅格我得到了 ArrayIndexOutOfBoundsException ,即使我用 TYPE_INT_ARGB 创建了 BufferedImage 。但是,使用 BufferedImage setRGB(...)方法对我有用。

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

我使用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);

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

看一下 BufferedImageFactory.java 类。

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

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

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

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

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

我有同样的问题,其他人试图应用这个问题的正确答案,我的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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top