如何将缓冲图像中的 IndexColorModel 设置为具有某些颜色和一种透明?

use*_*648 0 java graphics bufferedimage

我正在尝试绘制一个显示某物质量的条形图。

我创建了一个这样的缓冲图像:

 private static BufferedImage createBufferedImage(int width, int height) {
        int[] palette = {0x00ff00ff, 0xffff00ff, 0xff0000ff , 0xffff0000};
        IndexColorModel colorModel = new IndexColorModel(2, 4,
            palette, 0, true, 0, DataBuffer.TYPE_BYTE);
        return new BufferedImage(width,height,BufferedImage.TYPE_BYTE_INDEXED, colorModel);
    }  
Run Code Online (Sandbox Code Playgroud)

colorModel 应该有颜色:绿色、黄色、红色和一种透明的。条的颜色取决于质量,如下所示:

 private static Color getBarColor(double quality) {
        if (quality >= 0.70) {
            return Color.GREEN;
        } else if (quality >= 0.40) {
            return Color.YELLOW;
        } else {
            return Color.RED;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我正在创建图形来绘制条形并设置颜色:

Graphics2D g = image.createGraphics();
g.setColor(getBarColor(quality));
Run Code Online (Sandbox Code Playgroud)

但是,当我将质量的颜色设置为大于 0.7 时,它会绘制蓝色条,而对于低于 0.7 的质量,id 会绘制红色。

我认为问题出在我的调色板上,我没有正确设置颜色,当我试图获得绿色并且它不在那里时,设置的可能最接近。我认为格式 RRGGBBAA 应该用于 AA 设置透明度,ff 不透明,00 透明。我理解正确吗?问题出在哪儿?

我很感激任何帮助。

Rea*_*tic 5

您的问题是您假设 alpha 是您输入调色板的整数的低位部分。事实上,它是ARGB,而不是RGBA。

你可以用一个简单的循环来测试:

for ( int i = 0; i < 4; i++ ) {
    int red = colorModel.getRed(i);
    int green = colorModel.getGreen(i);
    int blue = colorModel.getBlue(i);
    int alpha = colorModel.getAlpha(i);

    System.out.printf("For index %d, red=%d, green=%d, blue=%d, alpha=%d%n", i,red,green,blue,alpha);
}
Run Code Online (Sandbox Code Playgroud)

结果将是:

对于索引 0,红色=255,绿色=0,蓝色=255,alpha=0
对于索引 1,红色=255,绿色=0,蓝色=255,alpha=255
对于索引 2,红色=0,绿色=0,蓝色=255,alpha=255
对于索引 3,红色=255,绿色=0,蓝色=0,alpha=255

现在,如果您希望颜色为绿色、黄色、红色和透明黄色,您应该使用:

int[] palette = { 0xff00ff00, 0xffffff00, 0xffff0000, 0x00ffff00 };
Run Code Online (Sandbox Code Playgroud)

但是你应该注意你还告诉它把第一个像素值作为透明而不是最后一个。您的颜色模型创建应该是:

IndexColorModel colorModel = new IndexColorModel(2,         // bits per pixel
                                                 4,         // size of color component array
                                                 palette,   // color map
                                                 0,         // offset in the map
                                                 true,      // has alpha
                                                 3,         // the pixel value that should be transparent
                                                 DataBuffer.TYPE_BYTE);
Run Code Online (Sandbox Code Playgroud)

当你这样做时,如果你再次运行上面的循环,你会得到结果:

对于索引 0,红色=0,绿色=255,蓝色=0,alpha=255
对于索引 1,红色=255,绿色=255,蓝色=0,alpha=255
对于索引 2,红色=255,绿色=0,蓝色=0,alpha=255
对于索引 3,红色=255,绿色=255,蓝色=0,alpha=0

事实上,如果您根本不在调色板值中使用 alpha 会更直接,因为您只想在一个特定值中指示透明度。为此,将hasAlpha参数设置为false而不是true

int[] palette = { 0x00ff00, 0xffff00, 0xff0000, 0xffff00 };
IndexColorModel colorModel = new IndexColorModel(2,
                                                 4,
                                                 palette,
                                                 0,
                                                 false,
                                                 3,
                                                 DataBuffer.TYPE_BYTE);
Run Code Online (Sandbox Code Playgroud)

这将为您提供相同的结果,但阅读和预测结果要容易得多。