【问题标题】:Detecting Alpha channel on transformed Image in UIImageView在 UIImageView 中检测转换图像上的 Alpha 通道
【发布时间】: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


    【解决方案1】:

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

    【讨论】:

    • 我试过但没有用,在问题中我用 Concat、Rotate 和 Scale 函数编辑了函数的版本,但没有成功。
    • 如果图像尺寸与图像不同,您可能需要移动到图像视图尺寸的中心。现在可能更容易将图像视图的完整大小绘制到上下文中,并将该 CGImage 写入磁盘,或在新视图中显示它,以确保正确应用转换。
    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 2022-12-20
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多