objective-c - 在 UIImageView 中检测转换图像上的 Alpha channel

标签 objective-c cocoa-touch uiimageview transformation

我正在使用此函数来检测 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];

}

此函数创建具有 super View 大小的图像(在我的例子中总是全屏)并从父 View 接收 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 channel 。

谢谢大家。

最佳答案

在绘制图像之前,使用 CGContextConcatCTM() 等函数将 ImageView 的变换应用到 CGContext。

关于objective-c - 在 UIImageView 中检测转换图像上的 Alpha channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8742606/

相关文章:

objective-c - 由于内存警告而卸载 View Controller 时如何保留状态?

objective-c - 抑制 XCode Analyzer 对象存储到 .. 错误中的潜在泄漏

iphone - UIView 不更新 UILabel

ios - 滚动时根据下载的图像高度使用 UITableViewAutomaticDimension 调整自定义表格单元格的高度

ios - 将图像从 UIImageView 复制到 UIView

objective-c - IOS 我可以在 appDelegate 上使用 AVAudioPlayer 吗?

ios - 在越狱设备上以编程方式发送短信

ios - 如何在ios中取消选中tableview上的所有单元格

ios - Pager View Controller 的 Root View 的大小与后续 View Controller 的大小不同

ios - AFNetworking 2.0 和背景图片