如何检测图像是灰度的

时间:2013-05-27 07:58:01

标签: ios objective-c image-processing

我需要确定图像是灰度(仅包含黑色,白色还是灰色阴影)或包含任何颜色。

我应该使用哪些库?

4 个答案:

答案 0 :(得分:11)

此信息存在于任何CGImageRef对象中。您可以从任何UIImage获取此对象。特别是,您感兴趣的是CGImageGetColorSpace。完成后,您可以在色彩空间上调用CGColorSpaceGetNumberOfComponents。应该只有三种可能性

CGColorSpaceGetNumberOfComponents返回1:此图像为灰度,已完成(一个例外:它可能只有alpha,但我怀疑你会发送任何类似的图像。如果你是,有一种方法可以通过CGAlphaInfo

确定图像是否仅为alpha

CGColorSpaceGetNumberOfComponents返回3:此图像是RGB,需要进一步分析以确定它是否为灰度(正如其他答案所述,循环像素,如果找到一个在哪里!(R = = G == B)那么它不是灰度。

CGColorSpaceGetNumberOfComponents返回4:此图像为CMYK,需要进一步分析。 CMYK中的所有灰度应为C == M == Y(通常它们将为0,因为否则会浪费墨水[此格式是专门针对打印机开发的]),K等于任何值。

CGColorSpaceGetNumberOfComponents返回其他内容:......好吧......哭泣

<强>更新

正如评论中所指出的,有一个更方便的功能来确定颜色模型。 CGColorSpaceGetModel会返回kCGColorSpaceModelMonochromekCGColorSpaceModelRGB等值。这将带来上述模糊性。之后,您可以检查RGB或CMYK的相同方式。

答案 1 :(得分:4)

以下是代码中的@borrrden答案:

- (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;}
}

答案 2 :(得分:2)

灰度背后的概念是,对于具有红色,绿色和蓝色值的像素,如果是Amount of Red = Amount of Green = Amount of Blue,那么您有一个带灰度的像素。如果图像的所有像素都处于这种情况下,则表示您具有灰度位图。

因此,您要做的就是遍历位图的RGB值。在iOS上,您可以使用以下代码访问图像的像素。

CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8 * data = CFDataGetBytePtr(pixelData);

答案 3 :(得分:0)

已批准答案的快速版本

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
    }
}