【发布时间】:2012-02-03 06:48:18
【问题描述】:
我正在使用这个函数来检测 UIImageView 的触摸点是否对应透明像素。
-(BOOL)isTransparency:(CGPoint)point
{
CGImageRef cgim = self.image.CGImage;
unsigned char pixel[1] = {0};
point.x = (point.x / (self.frame.size.width / CGImageGetWidth(cgim)));
point.y = (point.y / (self.frame.size.height / CGImageGetHeight(cgim)));
CGContextRef context = CGBitmapContextCreate(pixel,
1, 1, 8, 1, NULL,
kCGImageAlphaOnly);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(-point.x,
-(self.image.size.height - point.y),
CGImageGetWidth(cgim),
CGImageGetHeight(cgim)),
cgim);
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
return alpha < 0.01;
}
如果 UIImageView 转换未修改,则可以正常工作。但是当用户旋转图像时,变换矩阵被修改,这段代码得到了原始位置的图像,不对应于变换后的图像位置,我得到了错误的结果。
我的问题是如何检测 UIImageView 图像的触摸像素在旋转时是否透明?
谢谢。
编辑: -1.1 版-
嗨。感谢您的回答。我已经修改了代码,现在这个版本仍然像以前的版本一样工作:
-(BOOL)isTransparency:(CGPoint)point
{
CGImageRef cgim = self.image.CGImage;
NSLog(@"Image Size W:%lu H:%lu",CGImageGetWidth(cgim),CGImageGetHeight(cgim));
unsigned char pixel[1] = {0};
point.x = (point.x / (self.frame.size.width / CGImageGetWidth(cgim)));
point.y = (point.y / (self.frame.size.height / CGImageGetHeight(cgim)));
CGContextRef context = CGBitmapContextCreate(pixel,
1, 1, 8, 1, NULL,
kCGImageAlphaOnly);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextTranslateCTM(context, self.image.size.width * 0.5f, self.image.size.height * 0.5f);
CGContextConcatCTM(context, self.transform);
//CGContextScaleCTM(context, [self currentPercent]/100, [self currentPercent]/100);
//CGContextRotateCTM(context, atan2f(self.transform.b, self.transform.a));
CGContextTranslateCTM(context, -self.image.size.width * 0.5f, -self.image.size.height * 0.5f);
CGContextDrawImage(context, CGRectMake(-point.x,
-(self.image.size.height - point.y),
self.image.size.width,
self.image.size.height),
cgim);
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
NSLog(@"Is Transparent: %d",alpha < 0.01);
return alpha < 0.01;
}
我尝试使用几个函数将原始图像旋转和缩放到当前的旋转和大小,但没有成功。 :(
有什么帮助吗?
编辑: 1.2 版
我找到了解决此问题的解决方法。我决定创建一个大小等于屏幕大小的上下文,并根据当前的变换矩阵仅绘制触摸的对象。
之后,我为此上下文创建了一个位图,其中正确绘制了图像并将图像传递给仅适用于未转换图像的函数。
结果是可以正常工作。我不知道这是否是最佳方法,但可以。
代码如下:
-(BOOL)isTransparency:(CGPoint)point
{
UIGraphicsBeginImageContext(self.superview.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextTranslateCTM(context, [self center].x, [self center].y);
CGContextConcatCTM(context, [self transform]);
CGContextTranslateCTM(context,
-[self bounds].size.width * [[self layer] anchorPoint].x,
-[self bounds].size.height * [[self layer] anchorPoint].y);
[[self image] drawInRect:[self bounds]];
CGContextRestoreGState(context);
CGImageRef image = CGBitmapContextCreateImage(context);
CGImageRef viewImage = image;
return [self isTransparentPixel:point image:image];
}
这个函数创建超级视图大小的图像(在我的情况下总是全屏),并从父视图接收 UIKit 坐标系中的触摸点作为参数。
-(BOOL)isTransparentPixel:(CGPoint)point image:(CGImageRef)cgim
{
NSLog(@"Image Size W:%lu H:%lu",CGImageGetWidth(cgim),CGImageGetHeight(cgim));
unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel,
1, 1, 8, 1, NULL,
kCGImageAlphaOnly);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(-point.x,
-(self.superview.frame.size.height - point.y),
CGImageGetWidth(cgim),
CGImageGetHeight(cgim)),
cgim);
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
return alpha < 0.01;
}
此函数检测给定图像中给定像素的 Alpha 通道。
谢谢大家。
【问题讨论】:
标签: objective-c cocoa-touch uiimageview transformation