是否有可能知道 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 是合理的。
我的意思是等同于 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 是合理的。