如何获得特定点击点的UIImage的RGBA值 [英] how to get the RGBA value of UIImage in the specific clicked point
问题描述
我正在开发一个iPad应用程序,该应用程序在viewcontoller中具有多个UIImageViews.每个图像都有一些透明的部分.当用户单击图像时,我要测试他单击的图像区域是否不透明,然后我要执行一些操作
I am developing an iPad application that has multiple UIImageViews in a viewcontoller. each image has some transparent parts. when the user click on the image I want to test if the area of the image he clicked on was NOT transparent then I want to do some action
搜索后得出的结论是,我必须访问图像的原始数据并检查用户单击的点的alpha值
after searching I have reached the conclusion that I have to access the rawdata of the image and check the alpha value of the point the user clicked on
I used the solution found in here and it helped a lot. I modified the code so that if the point the user clicked on was transparent (alpha <1) then prent 0 else print 1. however, the result is not accurate in runtime. I sometimes get 0 where the point clicked is not transparent and viseversa. I think that there is a problem with the byteIndex value I am not sure that it returnes the color data at the point the user clicked
这是我的代码
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);
}
谢谢你
推荐答案
该方法很糟糕,因为它每次都会绘制完整图像,并且还依赖于确切的字节布局.
That method is bad as it draws the full image every time and also relies on the exact byte layout.
我建议只画一个1x1的上下文并获取其中的alpha
I propose to only draw into a 1x1 context and get alpha of that
- (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://stackoverflow.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;
}
这篇关于如何获得特定点击点的UIImage的RGBA值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!