I need to determine whether the image is grayscale (contains only black, white or shades of grey) or contains any color.
What libraries should I use for this?
This information is present in any CGImageRef
object. You can get this object from any UIImage
. In particular, the thing you would be interested in is CGImageGetColorSpace
. Once you have that, you can call CGColorSpaceGetNumberOfComponents
on the color space. There should only be three possibilities
CGColorSpaceGetNumberOfComponents
returns 1: This image is grayscale, finished (one exception: It could be alpha-only, but I doubt you'll be sending any images like that. If you are, there is a way to determine whether an image is alpha only through its CGAlphaInfo
)
CGColorSpaceGetNumberOfComponents
returns 3: This image is RGB, and further analysis is needed to determine if it is grayscale or not (as the other answer states, loop over the pixels and if you find one where !(R == G == B) then it is not grayscale.
CGColorSpaceGetNumberOfComponents
returns 4: This image is CMYK, and further analysis is needed. All grayscales in CMYK should be C == M == Y (usually they will be 0, as anything otherwise would be a waste of ink [this format was developed specifically with printers in mind]) with K equal to any value.
CGColorSpaceGetNumberOfComponents
returns something else: ...well...cry
UPDATE
As pointed out in the comments, there is a more convenient function for figuring out the color model. CGColorSpaceGetModel
will return values like kCGColorSpaceModelMonochrome
or kCGColorSpaceModelRGB
. This will take the ambiguity out of the above. After that you can check the same way for RGB or CMYK.
Here is @borrrden
answer in code:
- (BOOL)isGrayScale{
CGImageRef imageRef = [self CGImage];
CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef);
if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelRGB) {
CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef);
CFDataRef imageData = CGDataProviderCopyData(dataProvider);
const UInt8 *rawData = CFDataGetBytePtr(imageData);
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
int byteIndex = 0;
BOOL allPixelsGrayScale = YES;
for(int ii = 0 ; ii <width*height; ++ii)
{
int r = rawData[byteIndex];
int g = rawData[byteIndex+1];
int b = rawData[byteIndex+2];
if (!((r == g)&&(g == b))) {
allPixelsGrayScale = NO;
break;
}
byteIndex += 4;
}
CFRelease(imageData);
CGColorSpaceRelease(colorSpace);
return allPixelsGrayScale;
}
else if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome){
CGColorSpaceRelease(colorSpace); return YES;}
else {CGColorSpaceRelease(colorSpace); return NO;}
}
The concept behind the grayscale is that for a pixel with Red, Green and Blue values, if the Amount of Red = Amount of Green = Amount of Blue
, then you have an pixel with grayscale. If all pixels of your image is under this condition, it means you have a grayscale bitmap.
So, everything you gotta do is to loop over the RGB values of your bitmap. On iOS you can access the pixels of your image using the code below.
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8 * data = CFDataGetBytePtr(pixelData);
Swift Version of approved answer
extension UIImage {
func isGrayScale() -> Bool {
let imageRef = self.cgImage
let colorSpace = imageRef?.colorSpace
if colorSpace?.model == .rgb {
let dataProvider = imageRef?.dataProvider
let imageData = dataProvider?.data
let rawData = CFDataGetBytePtr(imageData!)
let width = imageRef?.width
let height = imageRef?.height
var byteIndex = 0
var allPixelsGrayScale = true
for _ in 0...width!*height! {
let red = rawData![byteIndex]
let green = rawData![byteIndex + 1]
let blue = rawData![byteIndex + 2]
if !((red == green) && (green == blue)) {
allPixelsGrayScale = false
break
}
byteIndex += 4
}
return allPixelsGrayScale
} else if colorSpace?.model == .monochrome {
return true
}
return false
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.