2

我正在尝试做类似于这个问题中所问的事情,但我并不真正理解该问题的答案,我不确定它是否是我需要的。

我需要的很简单,尽管我不太确定它是否容易。我想计算屏幕上某种颜色的像素数。我知道我们看到的每个“像素”实际上都是不同颜色的像素组合,例如绿色。所以我需要的是实际的颜色——用户看到的颜色。

例如,如果我创建了一个 UIView,将背景颜色设置为[UIColor greenColor],并将其尺寸设置为屏幕区域的一半(为了简单起见,我们可以假设状态栏是隐藏的,并且我们在 iPhone 上),我会期望这种“魔术方法”返回 240 * 160 或 38,400——屏幕面积的一半。

我不希望任何人写出这个“神奇的方法”,但我想知道

a) 如果可能的话

b) 如果是这样,如果它几乎是实时完成的

c) 如果又是这样,从哪里开始。我听说它可以用 OpenGL 完成,但我在这方面没有经验。

这是我的解决方案,感谢 Radif Sharafullin:

int pixelsFromImage(UIImage *inImage) {
    CGSize s = inImage.size;
    const int width = s.width;
    const int height = s.height;
    unsigned char* pixelData = malloc(width * height);

    int pixels = 0;

    CGContextRef context = CGBitmapContextCreate(pixelData,
                                                  width,            
                                                  height,            
                                                  8,           
                                                  width,            
                                                  NULL,            
                                                  kCGImageAlphaOnly);

    CGContextClearRect(context, CGRectMake(0, 0, width, height));

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), inImage.CGImage );

    CGContextRelease(context);

    for(int idx = 0; idx < width * height; ++idx) {
        if(pixelData[idx]) {
            ++pixels;
        }
    }

    free(pixelData);

    return pixels;
}
4

2 回答 2

4

有可能的。我做了类似的事情来计算透明像素的百分比,但由于我需要粗略的估计,我不是在看每个像素,而是在每 10 个像素,step变量在下面的代码中。

BOOL isImageErased(UIImage *inImage, float step, int forgivenessCount){
CGSize s = inImage.size;
int width = s.width;  
int height = s.height;   
unsigned char*  pixelData = malloc( width * height );  
int forgivenessCounter=0;


CGContextRef context = CGBitmapContextCreate ( pixelData,  
                                              width,            
                                              height,            
                                              8,           
                                              width,            
                                              NULL,            
                                              kCGImageAlphaOnly );   
CGContextClearRect(context, CGRectMake(0, 0, width, height));
CGContextDrawImage( context, CGRectMake(0, 0, width, height), inImage.CGImage );  
CGContextRelease( context );  
for (int x=0; x<width; x=x+step) {
    for (int y=0; y<height; y=y+step) {

        if(pixelData[y * width + x]) {
            forgivenessCounter++;
            if (forgivenessCounter==forgivenessCount) {
                free(pixelData);
                return FALSE;
            }

        };

    }
}



free( pixelData );

return TRUE;}

kCGImageAlphaOnly如果您传递经过预处理的灰度图像或修改API的设置,我相信此代码可以用于您的目的。

希望有帮助

于 2012-07-24T19:20:13.230 回答
0

用Swift 3编写的 eric.mitchell 解决方案

func pixelsFromImage(inImage: UIImage) -> Int {

    let width = Int(inImage.size.width)
    let height = Int(inImage.size.height)

    let bitmapBytesPerRow = width
    let bitmapByteCount = bitmapBytesPerRow * height

    let pixelData = UnsafeMutablePointer<UInt8>.allocate(capacity: bitmapByteCount)

    let colorSpace = CGColorSpaceCreateDeviceGray()

    let context = CGContext(data: pixelData,
                            width: width,
                            height: height,
                            bitsPerComponent: 8,
                            bytesPerRow: bitmapBytesPerRow,
                            space: colorSpace,
                            bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.alphaOnly.rawValue).rawValue)!

    let rect = CGRect(x: 0, y: 0, width: width, height: height)
    context.clear(rect)
    context.draw(inImage.cgImage!, in: rect)

    var pixels = 0

    for x in 0...width {
        for y in 0...height {

            if pixelData[y * width + x] > 0 {
                pixels += 1
            }
        }
    }


    free(pixelData)

    return pixels
}
于 2016-12-12T15:18:41.163 回答