简体   繁体   English

检查 NSImage 是否为模板图像的最快方法

[英]Fastest way to check if NSImage is a template image

Let's say you have a NSImage with NSBitmapImageRep (raster image) of 16x16 pixels.假设您有一个 NSImage,其 NSBitmapImageRep(光栅图像)为 16x16 像素。 It can be a color image or contain only black pixels with alpha channel.它可以是彩色图像或仅包含带有 Alpha 通道的黑色像素。

When it only has black pixels, I can set .isTemplate for the NSImage and handle it correspondingly.当它只有黑色像素时,我可以为 NSImage 设置 .isTemplate 并进行相应的处理。

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.即使是 16x16 尺寸,处理 10-20 张图像也需要大约一秒钟的时间。 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;
}

Pure black images are in your category, is color image or only pixels with alpha channel?纯黑色图像属于您的类别,是彩色图像还是仅具有 Alpha 通道的像素? Why not judge the image type by the number of channels?为什么不通过通道数来判断图像类型呢? RGBX or only A. RGBX 或仅 A。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM