【问题标题】:BufferedImage unexpectedly changing colorBufferedImage 意外改变颜色
【发布时间】:2016-05-19 04:25:50
【问题描述】:

我有以下代码,它创建灰度 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% 的像素中出现了奇怪的行为,我设置了颜色,然后它的值与之前设置的不同。我设置颜色的方式不对吗?

【问题讨论】:

  • @JoopEggen 刚刚测试过,你是对的,你应该把它作为答案发布。

标签: java bufferedimage


【解决方案1】:

这是您的解决方案:禁止 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 值。栅格为您完成所有转换工作。

【讨论】:

    【解决方案2】:

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

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

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

    因此,您可能会看到由于转换导致的不匹配。

    【讨论】:

    • 不幸的是,我需要它是BufferedImage.TYPE_BYTE_GRAY。我不是用这条线创建灰度颜色:int color = (0xff &lt;&lt; 24) | (average &lt;&lt; 16) | (average &lt;&lt; 8) | average; 吗?感谢您的帮助
    • 是的,我并不是要暗示您应该更改颜色模型,只是颜色模型正在引入一些导致您的问题的转换。您正在制作的当前颜色在 ARGB 模型中,因此您需要找出灰度模型颜色格式并以这种方式制作颜色。
    【解决方案3】:

    猜测:

    删除 (0xff = 128 应用透明度,25% 可能是错误的颜色映射(非常疯狂的猜测)。

    【讨论】:

    • 不确定,如果删除 (0xff &lt;&lt; 24) | 真的可以解决问题。错误似乎在显着位,而不是 alpha 通道。
    • 抱歉,我帮不上忙,试试int average = (int) (Math.random() * 127);average | 0xff_00_00:_00。标志扩展不可能发生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多