在 IOS 开发中,有时候需要获取图像中某个像素点的颜色,返回 UIColor 值。网上收集资料,参考各种方案,最后总结如下:
- (UIColor *)colorAtPixel:(CGPoint)point {
// 如果点超出图像范围,则退出
if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point)) {
return nil;
}
// Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
NSInteger pointX = trunc(point.x);
NSInteger pointY = trunc(point.y);
CGImageRef cgImage = self.CGImage;
NSUInteger width = self.size.width;
NSUInteger height = self.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * 1;
NSUInteger bitsPerComponent = 8;
unsigned char pixelData[4] = { 0, 0, 0, 0 };
CGContextRef context = CGBitmapContextCreate(pixelData,
1,
1,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);
// Draw the pixel we are interested in onto the bitmap context
CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
CGContextRelease(context);
// 把[0,255]的颜色值映射至[0,1]区间
CGFloat red = (CGFloat)pixelData[0] / 255.0f;
CGFloat green = (CGFloat)pixelData[1] / 255.0f;
CGFloat blue = (CGFloat)pixelData[2] / 255.0f;
CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
如果还需要将返回的 UIColor 值转化成 RGBA 值,则可直接修改上述方法,直接返回相应的数值即可。也可另外封装一个 UIColor 转换成 RGB 值的方法:
- (CGFloat)RGBValueFromUIColor:(UIColor *)color {
//获得RGB值描述
NSString *RGBValue = [NSString stringWithFormat:@"%@",color];
//将RGB值描述分隔成字符串
NSArray *RGBArr = [RGBValue componentsSeparatedByString:@" "];
//获取红色值
CGFloat r = [[RGBArr objectAtIndex:1] floatValue] * 255;
//获取绿色值
CGFloat g = [[RGBArr objectAtIndex:2] floatValue] * 255;
//获取蓝色值
CGFloat b = [[RGBArr objectAtIndex:3] floatValue] * 255;
NSLog(@"----------%f--%f--%f----------",r,g,b);
}
就是这么简单!
下面对内部一些需要了解的方法作简要介绍:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
创建一个通用的 RGB 色彩空间。
注意点:使用 RGB 模式的颜色空间(在Quartz 2D 中凡是使用带有 Create 或者 Copy 关键字方法创建的对象,在使用后一定要使用对应的方法释放(如,本实例中:CGColorSpaceRelease(colorSpace);
))。
CGBitmapContextCreate 函数原型:
CGContextRef CGBitmapContextCreate (
void *data,
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bytesPerRow,
CGColorSpaceRef colorspace,
CGBitmapInfo bitmapInfo
);
data:指向要渲染的绘制内存的地址。这个内存块的大小至少是(bytesPerRow*height)个字节;
width:bitmap的宽度,单位为像素;
height:bitmap的高度,单位为像素;
bitsPerComponent:内存中像素的每个组件的位数。例如,对于32位像素格式和 RGB 颜色空间,应该将这个值设为8;
bytesPerRow:bitmap的每一行在内存所占的比特数;
colorspace:bitmap上下文使用的颜色空间;
bitmapInfo:指定 bitmap 是否包含 alpha 通道,像素中 alpha 通道的相对位置,像素组件是整形还是浮点型等信息的字符串。
当调用这个函数的时候,Quartz 创建一个位图绘制环境,也就是位图上下文。当你向上下文中绘制信息时,Quartz 把你要绘制的信息作为位图数据绘制到指定的内存块。一个新的位图上下文的像素格式由三个参数决定:每个组件的位数,颜色空间,alpha 选项。alpha 值决定了绘制像素的透明性。
CGContextSetBlendMode :设置混合模式,具体细节不赘述,给个参考资料:http://blog.csdn.net/cpskiss/article/details/7056256
CGContextTranslateCTM : 平移坐标系统。该方法相当于把原来位于 (0, 0) 位置的坐标原点平移到 (tx, ty) 点。在平移后的坐标系统上绘制图形时,所有坐标点的 X 坐标都相当于增加了 tx,所有点的 Y 坐标都相当于增加了 ty。对应的还有缩放坐标系统和旋转坐标系统,此处不展开说,后面有机会再分享。