java-为什么ImageIO.write()方法修改像素值?
作者:互联网
我正在尝试运行一个简单的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());
}
}
}
不幸的是,这两个图像像素数据经常且不可预测地不同.有人可以帮我找到一种方法,以便至少对于图像类型不修改值吗?
编辑这里是上述过程中失败的图像
解决方法:
确保使用正确的颜色模型进行读写.
根据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.
(强调我的)
标签:javax-imageio,image,bufferedimage,java 来源: https://codeday.me/bug/20191122/2061753.html