是否有可能知道 SWT 图像是灰度图像还是 RGB 图像?

is it possible to know if a SWT Image is grayscale or RGB?

我的意思是等同于 AWT 的 BufferedImage#getType(),或者允许我编写简单 isGrayscale() 方法的其他东西。

我正在使用 SWT,因为我需要读取 AWT 无法打开的 TIF 图像。

我的objective是在任意图上画(带颜色),如果是灰度图,我得先创建一个RGB图,把黑白像素复制进去再画。知道图像是否已经是 RGB 将节省转换过程。


最终代码,基于以下 Alex 的解决方案

我使用总体标准偏差来更好地控制 RGB 值。

private static final double GRAY_LEVEL_STD_SIGMA = 2.4;
public static boolean isShadowOfGray(RGB color) {
    // pure shadow
    if (color.red == color.green && color.green == color.blue) {
        return true;
    }
    // Standard deviation filter
    double mean = (color.red + color.green + color.blue) / 3;
    double std = Math.sqrt((
        Math.pow(color.red - mean, 2) + 
        Math.pow(color.green - mean, 2) + 
        Math.pow(color.blue - mean, 2)) / 3);
    return (std < GRAY_LEVEL_STD_SIGMA);
}

顺便说一下,我认为 "direct" 调色板图像始终是 RGB(它们不包含来自 getRGBs() 的直接值)。解决方案代码没有用于此类图像的专用像素循环。

你可以尝试自己写这个方法。如果图像是灰度的,则意味着其调色板中的所有颜色都具有相同的 R、G、B。

public static boolean isGrayscale(Image image) {
    ImageData data = image.getImageData(); // or new ImageData("C:\image.bmp"); 
    RGB[] rgbs = data.getRGBs();
    for (int i = 0; i < rgbs.length; i++) {
       if (!isShadowOfGray(rgbs[i])) {
          return false;
       }
    }
    return true;
}

public static boolean isShadowOfGray(RGB color) {
   return color.red == color.green && color.green == color.blue;
}

P.S。我想了一下,决定添加一些关于灰色阴影的词。在理想世界中,灰色阴影满足条件 r == g == b。但有时(特别是由于 jpeg 图像的压缩)颜色可能类似于 (201, 198, 199)。从技术上讲,它仍然是灰色的,人类无法将这种颜色识别为非灰色,但上述算法可以。因此,如果每个通道与平均值之间的绝对差小于某个阈值,我建议计算 r、g、b 的平均值并将图像检测为灰度。我相信 threshold = 5 是合理的。