如何获取特定点击点中UIImage的RGBA值
Posted
技术标签:
【中文标题】如何获取特定点击点中UIImage的RGBA值【英文标题】:how to get the RGBA value of UIImage in the specific clicked point 【发布时间】:2013-05-23 20:05:54 【问题描述】:我正在开发一个 iPad 应用程序,它在 viewcontoller 中有多个 UIImageViews。每个图像都有一些透明部分。当用户点击我想测试的图像时,如果他点击的图像区域不透明,那么我想做一些动作
经过搜索,我得出结论,我必须访问图像的原始数据并检查用户点击的点的 alpha 值
我使用了here 中的解决方案,它帮助很大。我修改了代码,如果用户单击的点是透明的(alpha byteIndex 值有问题我不确定它是否会在用户单击时返回颜色数据
这是我的代码
CGPoint touchPoint;
- (void)viewDidLoad
[super viewDidLoad];
[logo addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]];
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.view];
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
int x = touchPoint.x;
int y = touchPoint.y;
[self getRGBAsFromImage:img atX:x andY:y];
- (void)getRGBAsFromImage:(UIImage*)image atX:(int)xx andY:(int)yy
// First get the image into your data buffer
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
byteIndex += 4;
if (alpha < 1)
NSLog(@"0");
// here I should add the action I want
else NSLog(@"1");
free(rawData);
提前谢谢你
【问题讨论】:
【参考方案1】:这种方法很糟糕,因为它每次都绘制完整的图像,并且还依赖于确切的字节布局。
我建议只绘制一个 1x1 的上下文并获得它的 alpha
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
int x = touchPoint.x;
int y = touchPoint.y;
CGFloat alpha = [self getAlphaFromImage:img atX:x andY:y];
if(alpha<1)
…
- (CGFloat)getAlphaFromImage:(UIImage*)image atX:(NSInteger)xx andY:(NSInteger)yy
// Cancel if point is outside image coordinates
if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), CGPointMake(xx,yy)))
return 0;
// Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
// Reference: http://***.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage
NSInteger pointX = xx;
NSInteger pointY = yy;
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);
CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
return alpha;
【讨论】:
添加了代码。内联输入,所以可能不是 100% 好的......但我也有一个很好的参考:D 感谢您的快速响应。从我使用的方法来看,您的方法看起来已经更好了。但是,问题仍然存在:/我没有得到准确的 alpha 值。我开始认为图像本身的格式可能有问题,所以这里是图像,也许你可以找到一些 Image。 .. CGImageRef 的另一件事 cgImage = self.CGImage;你的意思是 CGImageRef cgImage = myImage.CGImage; ??因为我收到了一个错误。再次感谢 好吧,我遇到了同样的问题,我每次都没有得到正确的 alpha 值。知道可能是什么问题吗? 您是否使用缩放版本的图像? ...可能通过可缩放的 UIImageView 或通过变换或... 图像的模式是按比例填充,如果这是您的意思,除了我不对图像进行任何修改或转换以上是关于如何获取特定点击点中UIImage的RGBA值的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Javascript 通过 CSS 获取确切的 RGBa 值?