有效地检测仅触摸UIImageView的非透明像素

hpi*_*que 24 iphone image-processing uiimageview hittest ios

你如何才能有效地检测到a的非透明像素上的触摸UIImageView

考虑下面的图像,显​​示为UIImageView.目标是仅在触摸发生在图像的非透明(在这种情况下为黑色)区域时使手势识别器响应.

在此输入图像描述

思路

  • 覆盖hitTest:withEvent:或者pointInside:withEvent:,尽管这种方法可能非常低效,因为这些方法在触摸事件期间被多次调用.
  • 检查单个像素是否透明可能会产生意外结果,因为手指大于一个像素.检查命中点周围的像素圆形区域,或尝试找到朝向边缘的透明路径可能会更好.

奖金

  • 区分图像的外部和内部透明像素会很好.在该示例中,零内的透明像素也应被视为有效.
  • 如果图像有变换会发生什么?
  • 图像处理可以硬件加速吗?

OC *_*ard 18

这是我的快速实现:(基于检索UIImage的像素alpha值)

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    //Using code from https://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage

    unsigned char pixel[1] = {0};
    CGContextRef context = CGBitmapContextCreate(pixel,
                                                 1, 1, 8, 1, NULL,
                                                 kCGImageAlphaOnly);
    UIGraphicsPushContext(context);
    [image drawAtPoint:CGPointMake(-point.x, -point.y)];
    UIGraphicsPopContext();
    CGContextRelease(context);
    CGFloat alpha = pixel[0]/255.0f;
    BOOL transparent = alpha < 0.01f;

    return !transparent;
}
Run Code Online (Sandbox Code Playgroud)

这假定图像与的图像位于相同的坐标空间中point.如果继续缩放,则可能必须point在检查像素数据之前进行转换.

看起来很快对我工作.我估计约.此方法调用0.1-0.4 ms.它没有内部空间,可能不是最佳的.


ser*_*gio 6

在github上,你可以找到Ole Begemann的一个项目,它延伸UIButton到只能检测按钮图像不透明的触摸.

既然UIButton是一个子类UIView,适应它UIImageView应该是直截了当的.

希望这可以帮助.