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

标签 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());
            }

        }
}

不幸的是,两幅图像的像素数据经常不同且不可预测。有人可以帮我找到一种方法,至少对于图像类型,值不会被修改吗? 编辑这是一张在上述过程中失败的图像

For this image the background color is changed

最佳答案

确保您使用正确的阅读和写作颜色模型。

根据BufferedImage.getRGB() documentation ,

Returns an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) and default sRGB color space, from a portion of the image data. Color conversion takes place if the default model does not match the image ColorModel. There are only 8-bits of precision for each color component in the returned data when using this method. With a specified coordinate (x, y) in the image, the ARGB pixel can be accessed in this way:

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

[编辑]

您需要使用构造函数BufferedImage(width, height, type, ColorModel),如Javadoc for your image type 中所示(TYPE_BYTE_BINARY):

When this type is used as the imageType argument to the BufferedImage constructor that takes an imageType argument but no ColorModel argument, a 1-bit image is created with an IndexColorModel with two colors in the default sRGB ColorSpace: {0, 0, 0} and {255, 255, 255}.

Images with 2 or 4 bits per pixel may be constructed via the BufferedImage constructor that takes a ColorModel argument by supplying a ColorModel with an appropriate map size.

(强调我的)

关于java - 为什么 ImageIO.write() 方法修改像素值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19124591/

相关文章:

java - 如何在给定文本中找到给定单词的所有排列?

java - JAX-WS 生成具有 protected 或私有(private)构造函数的 WS 客户端

jquery - 在网页中快速加载图像

php - 在服务器上存储大量图像的建议[PHP]

c++ - 来自 std::vector<std::uint32_t> 保存数组中原始 RGB 值的 CBitmap

java - Maven MOJO - 在另一个参数中使用一个参数

java - 在java中格式化字符串以完美匹配

java - 缩放后,如果没有不相关的 imageIcon,图像将不会显示

java - JComponents 没有显示图片背景?

java - 旋转 BufferedImage 会改变其颜色