为什么ImageIO.write()方法会修改像素值?

时间:2013-10-01 19:45:38

标签: java image bufferedimage javax.imageio

我正在尝试运行一个尝试执行以下操作的简单Java程序:从给定图像中提取像素数据。然后使用此数据创建相同类型的新图像。问题在于,当我读取此创建图像的像素数据时,像素值与我写入的像素值不同。这不仅发生在.jpg图像上,也发生在某些.png图像上(因此它甚至不限于图像类型)。 这是我的代码:

package com.alex;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Test {

    public static void main(String[] args) {
        try{
            // Read source image
            BufferedImage img = ImageIO.read(new File("D:/field.png")); 


            int width = img.getWidth();
            int height = img.getHeight();
            int[] imagePixels = new int[width*height];
            img.getRGB(0, 0, width, height, imagePixels, 0, width);

            // Create copy image
            BufferedImage destImg = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
            destImg.setRGB(0, 0, img.getWidth(), img.getHeight(), imagePixels, 0, img.getWidth());
            File out = new File("D:/test.png");
            ImageIO.write(destImg, "png", out);

            // Extract copy image pixels
            BufferedImage copy = ImageIO.read(new File("D:/test.png"));
            int width1 = copy.getWidth();
            int height1 = copy.getHeight();
            int[] extractedPixels = new int[width1*height1];
            copy.getRGB(0, 0, width1, height1, extractedPixels, 0, width1);

            System.out.println("The 2 dimensions are " + imagePixels.length + " " + extractedPixels.length );

            // Compare the piels from the 2 images
            int k=0;
            for(int i=0; i<imagePixels.length; i++) {
                if(imagePixels[i] != extractedPixels[i]) {
                    k++;
                }
            }
            System.out.println("Number of different pixels was: " + k);
            }catch(IOException e) {
            System.out.println("Exception was thrown during reading of image: " + e.getMessage());
            }

        }
}

不幸的是,2个图像像素数据经常不可预测且不可预测。有人可以帮我找一个方法,这样,至少对于图像类型,这些值不会被修改吗? 编辑以下是上述过程中失败的图片

For this image the background color is changed

2 个答案:

答案 0 :(得分:3)

确保使用正确的颜色模型进行读写。

根据BufferedImage.getRGB() documentation

  

从图像数据的一部分返回默认RGB颜色模型(TYPE_INT_ARGB)和默认sRGB颜色空间中的整数像素数组。如果默认模型与图像ColorModel不匹配,则会进行颜色转换。使用此方法时,返回数据中的每个颜色分量只有8位精度。使用图像中的指定坐标(x,y),可以通过以下方式访问ARGB像素:

pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)];

<强> [编辑]

您需要使用构建器BufferedImage(width, height, type, ColorModel),如Javadoc for your image typeTYPE_BYTE_BINARY)中所示:

  

当此类型用作BufferedImage构造函数的imageType参数时,该构造函数采用imageType参数但无ColorModel参数,使用默认sRGB中带有两种颜色的IndexColorModel创建1位图像 ColorSpace:{0,0,0}和{255,255,255}。

     

每像素2或4位的图像可以通过 BufferedImage构造函数构造,该构造函数通过提供具有适当地图大小的ColorModel来获取ColorModel参数

(强调我的)

答案 1 :(得分:0)

试试这个 首先在两个数组中打印相同的索引 如果结果不相同意味着您在颜色模式下出现问题,但如果相同意味着您的比较不起作用。