过程如下:
- 生成位图上下文
- 在上下文绘制图片
- 生成图片数据
- 计算对应点的数据偏移位置
- 取出像素值
代码如下:
- (UIColor*)getPixelColorAtLocation:(CGPoint)point {
UIColor* color = nil;
//创建像素位图
CGImageRef inImage = self.cView.image.CGImage;
//创建一个bitmap context ARGB(Alpa, Red, Green, Blue)格式每个像素用占4字节,32个bit
CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
if (cgctx == NULL) { return nil; }
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
//把image画到bitmap context上。
CGContextDrawImage(cgctx, rect, inImage);
//图片数据的指针
unsigned char* data = CGBitmapContextGetData(cgctx);
if (data != NULL) {
//用x y计算data偏移位置,每个像素4bytes
@try {
int offset = 4*((w*round(point.y))+round(point.x));//计算像素位置
NSLog(@"offset: %d", offset);
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);
color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
}
@catch (NSException * e) {
NSLog(@"%@",[e reason]);
}
@finally {
}
}
//释放绘图上下文
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);
//计算每一行数据字节大小,每一个像素是4 bytes:red,green,blue,alpha各8 bits
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
//RGB颜色空间:不同颜色在不同的维度上取值最终组成一种颜色的过程
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,//指向绘图操作被渲染的内存区域,这个内存区域大小应该为(bytesPerRow*height)个字节。如果对绘制操作被渲染的内存区域并无特别的要求,那么可以传递NULL给参数date。
pixelsWide,//被渲染内存区域的宽度
pixelsHigh,//被渲染内存区域的高度
8,//渲染内存区域中组件在屏幕每个像素点上需要使用的bits位,举例来说,如果使用32-bit像素和RGB颜色格式,那么RGBA颜色格式中每个组件在屏幕每个像素点上需要使用的bits位就为32/4=8。
bitmapBytesPerRow,//渲染内存区域中每行所使用的bytes位数
colorSpace,//颜色空间
kCGImageAlphaPremultipliedFirst);//指定被渲染内存区域的“视图”是否包含一个alpha(透视)通道以及每个像素相应的位置,除此之外还可以指定组件式是浮点值还是整数值,此处代表着图片的BGR值是已乘以Alpha值
if (context == NULL)
{
free(bitmapData);
fprintf(stderr,"Context not created!");
}
//释放颜色空间
CGColorSpaceRelease(colorSpace);
return context;
}
网友评论