BufferedImage意外地改变了颜色

我有以下代码,它创建灰度BufferedImage,然后设置每个像素的随机颜色。

import java.awt.image.BufferedImage; public class Main { public static void main(String[] args) { BufferedImage right = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_GRAY); int correct = 0, error = 0; for (int i = 0; i < right.getWidth(); i++) { for (int j = 0; j < right.getHeight(); j++) { int average = (int) (Math.random() * 255); int color = (0xff << 24) | (average << 16) | (average << 8) | average; right.setRGB(i, j, color); if(color != right.getRGB(i, j)) { error++; } else { correct++; } } } System.out.println(correct + ", " + error); } } 

大约25-30%的像素出现奇怪的行为,我设置颜色,然后它具有不同于先前设置的值。 我用错误的方式设置颜色吗?

这是你的解决方案:禁止getRGB并使用Raster(比getRGB更快更容易)或甚至更好的DataBuffer(最快但你必须处理编码):

 import java.awt.image.BufferedImage; public class Main { public static void main(String[] args) { BufferedImage right = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_GRAY); int correct = 0, error = 0; for (int x=0 ; x < right.getWidth(); x++) for (int j = 0; j < right.getHeight(); j++) { int average = (int) (Math.random() * 255) ; right.getRaster().setSample(x, y, 0, average) ; if ( average != right.getRaster().getSample(x, y, 0) ) error++ ; else correct++; } System.out.println(correct + ", " + error); } } 

在你的情况下,getRGB很糟糕,因为编码是一个字节数组(8位),你必须用getRGB操作RGB值。 栅格为您完成所有转换工作。

我认为您的问题与图像类型(BufferedImage构造函数的第三个参数)有关。 如果您将类型更改为BufferedImage.TYPE_INT_ARGB ,那么您将获得100%正确的结果。

查看BufferedImage.getRGB(int,int)的文档,当您获得的RGB不是默认颜色空间时会有一些转换

返回默认RGB颜色模型(TYPE_INT_ARGB)和默认sRGB颜色空间中的整数像素。 如果此默认模型与图像ColorModel不匹配,则会进行颜色转换。

所以你可能会看到由于转换造成的不匹配。

胡乱猜测:

删除(0xff << 24)| 这是alpha通道,颜色是不透明/不透明的。 给定是/否透明和平均<或> = 128应用透明度,25%可能是错误的颜色映射(非常疯狂的猜测)。