Let's say you have a NSImage with NSBitmapImageRep (raster image) of 16x16 pixels. It can be a color image or contain only black pixels with alpha channel.
When it only has black pixels, I can set .isTemplate for the NSImage and handle it correspondingly.
The question is - how do you quickly detect it has black pixels only?
What is the fastest way to check if provided image is a template?
Here is how I do it. It works, but requires moving through all the pixels and check them one-by-one. Even with 16x16 size it takes about a second for 10-20 images to process. So I am looking for a more optimized approach:
+ (BOOL)detectImageIsTemplate:(NSImage *)image
{
BOOL result = NO;
if (image)
{
// If we have a valid image, assume it's a template until we face any non-black pixel
result = YES;
NSSize imageSize = image.size;
NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef ctx = CGBitmapContextCreate(NULL,
imageSize.width,
imageSize.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedLast);
NSGraphicsContext* gctx = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:NO];
[NSGraphicsContext setCurrentContext:gctx];
[image drawInRect:imageRect];
// ......................................................
size_t width = CGBitmapContextGetWidth(ctx);
size_t height = CGBitmapContextGetHeight(ctx);
uint32_t* pixel = (uint32_t*)CGBitmapContextGetData(ctx);
for (unsigned y = 0; y < height; y++)
{
for (unsigned x = 0; x < width; x++)
{
uint32_t rgba = *pixel;
uint8_t red = (rgba & 0x000000ff) >> 0;
uint8_t green = (rgba & 0x0000ff00) >> 8;
uint8_t blue = (rgba & 0x00ff0000) >> 16;
if (red != 0 || green != 0 || blue != 0)
{
result = NO;
break;
}
pixel++; // Next pixel
}
if (result == NO) break;
}
// ......................................................
[NSGraphicsContext setCurrentContext:nil];
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
}
return result;
}