Reputation: 2278
I mean a equivalent of AWT's BufferedImage#getType()
, or something else which allows me to write a simple isGrayscale()
method.
I'm using SWT because I need to read TIF images, which AWT cannot open.
My objective is to draw (with color) on arbitrary image, and if it is grayscale, I have to first create an RGB image and copy B&W pixels in it before drawing. Knowing if the image is already RGB will save that transformation process.
Final code, based on Alex's solution below
I used population standard deviation for finer control of RGB values.
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);
}
By the way, i consider "direct" palette images to always be RGB (they do not contains direct values from getRGBs()). The solution code does not have a dedicated pixel loop for that kind of images.
Upvotes: 0
Views: 177
Reputation: 3407
You could try to write this method by your own. If an image is grayscale it means all colors in its' pallette have the same 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. I thought a bit and decided to add couple words about shadows of gray. In the ideal world a shadow of gray satisfies the condition r == g == b. But sometimes (especially due to compression in jpeg images) a color could be like (201, 198, 199). Technically it's still gray, a human can't recognize this color as non-gray, but above algorithm can. So I'd recommend to calculate the average of r,g,b and detect image as grayscale if absolute difference between each channel and average is less than some threshold. I believe threshold = 5 is reasonable.
Upvotes: 1