我正在尝试做类似this question中提到的事情,但我真的不明白给出这个问题的答案,我不确定这是否是我需要的。
我需要的是简单的,虽然我不太确定这很容易。我想计算屏幕上某种颜色的像素数。我知道我们看到的每个“像素”实际上是不同颜色的像素的组合,看起来像是绿色。所以我需要的是实际颜色 - 用户看到的颜色。
例如,如果我创建了一个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;
}
答案 0 :(得分:4)
有可能。我已经做了类似的事情来计算透明像素的百分比,但由于我需要粗略估计,我没有看到每个像素,而是在下面的代码中的每个第十个像素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;}
如果您传递预处理的灰度图像或修改API的kCGImageAlphaOnly
设置,我相信此代码可用于您的目的。
希望有所帮助
答案 1 :(得分: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
}