http://blog.csdn.net/ssanonymity/article/details/7643236
最近写一个应用,需要对图像中某一个像素点的颜色进行取样,并检测是否与特定颜色一致或相近,解决的办法如下:
一、像素点颜色取样(代码参考国外一篇文章,在最后列出)
- + (UIColor*) getPixelColorAtLocation:(CGPoint)point inImage:(UIImage *)image {
- UIColor* color = nil;
- CGImageRef inImage = image.CGImage;
- CGContextRef cgctx = [DetectColour createARGBBitmapContextFromImage:
- inImage];
- if (cgctx == NULL) { return nil; /* error */ }
- size_t w = CGImageGetWidth(inImage);
- size_t h = CGImageGetHeight(inImage);
- CGRect rect = {{0,0},{w,h}};
- CGContextDrawImage(cgctx, rect, inImage);
- unsigned char* data = CGBitmapContextGetData (cgctx);
- if (data != NULL) {
- int offset = 4*((w*round(point.y))+round(point.x));
- int alpha = data[offset];
- int red = data[offset+1];
- int green = data[offset+2];
- int blue = data[offset+3];
- NSLog(@"offset: %i colors: RGB A %i %i %i %i",offset,red,green,
- blue,alpha);
- NSLog(@"x:%f y:%f", point.x, point.y);
- color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:
- (blue/255.0f) alpha:(alpha/255.0f)];
- }
- CGContextRelease(cgctx);
- if (data) { free(data); }
- return color;
- }
- + (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
- CGContextRef context = NULL;
- CGColorSpaceRef colorSpace;
- void * bitmapData;
- int bitmapByteCount;
- int bitmapBytesPerRow;
- size_t pixelsWide = CGImageGetWidth(inImage);
- size_t pixelsHigh = CGImageGetHeight(inImage);
- bitmapBytesPerRow = (pixelsWide * 4);
- bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
- colorSpace = CGColorSpaceCreateDeviceRGB();
- if (colorSpace == NULL)
- {
- fprintf(stderr, "Error allocating color space\n");
- return NULL;
- }
- bitmapData = malloc( bitmapByteCount );
- if (bitmapData == NULL)
- {
- fprintf (stderr, "Memory not allocated!");
- CGColorSpaceRelease( colorSpace );
- return NULL;
- }
- context = CGBitmapContextCreate (bitmapData,
- pixelsWide,
- pixelsHigh,
- 8,
- bitmapBytesPerRow,
- colorSpace,
- kCGImageAlphaPremultipliedFirst);
- if (context == NULL)
- {
- free (bitmapData);
- fprintf (stderr, "Context not created!");
- }
- CGColorSpaceRelease( colorSpace );
- return context;
- }
二、颜色匹配计算
一是精确的匹配,通过生成两个CGColor,利用CGColorEqualToColor函数进行对比即可,如下:
- //生成采样对照颜色(黑色)
- UIColor* sampleColor = [UIColor colorWithRed:(0/255.0f) green:(0/255.0f)
- blue:(0/255.0f) alpha:(255/255.0f)];
- //比较
- if (CGColorEqualToColor(detectedColor.CGColor, sampleColor.CGColor)) {
- //处理
- }
二是模糊的匹配,在RGB色彩空间下, 每个像素点的颜色有四个通道(R, G, B, Alpha),比较
两个颜色是否一致的方法,可以通过比较其向量的方式来进行,如下:
- //获取颜色分量
- const CGFloat* components = CGColorGetComponents(detectedColor.CGColor);
- CGFloat Red, Green, Blue, Alpha;
- Alpha = components[0];
- Red = components[0+1];
- ....
- //向量比较
- float difference = pow( pow((red1 - red2), 2) + pow((green1 - green2), 2) +
- pow((blue1 - blue2), 2), 0.5 );
至于阀值的设定,就需要大家根据实际情况来调整了,一般可设置为85,如果严格一点,则小一点;宽松一点,则可以设大一点。
参考文章: http://www.markj.net/iphone-uiimage-pixel-color/