3

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

我应该为此使用哪些库?

4

4 回答 4

12

此信息存在于任何CGImageRef对象中。您可以从任何UIImage. 特别是,您会感兴趣的是CGImageGetColorSpace. 一旦你有了它,你就可以调用CGColorSpaceGetNumberOfComponents颜色空间。应该只有三种可能

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

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

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

CGColorSpaceGetNumberOfComponents返回别的东西:...嗯...哭

更新

正如评论中所指出的,有一个更方便的函数来计算颜色模型。 CGColorSpaceGetModel将返回类似kCGColorSpaceModelMonochromeor的值kCGColorSpaceModelRGB。这将消除上述歧义。之后,您可以检查 RGB 或 CMYK 的相同方式。

于 2013-05-27T10:18:02.953 回答
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;}
}
于 2013-07-29T08:53:45.373 回答
2

灰度背后的概念是,对于具有红色、绿色和蓝色值的像素,如果Amount of Red = Amount of Green = Amount of Blue,那么您有一个具有灰度的像素。如果您的图像的所有像素都处于这种状态,则意味着您有一个灰度位图。

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

CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8 * data = CFDataGetBytePtr(pixelData);
于 2013-05-27T08:05:40.113 回答
1

批准答案的 Swift 版本

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
    }
}
于 2019-08-19T09:57:48.517 回答