检测两个图像之间的像素碰撞/重叠



我有两个UIImageViews包含一些透明区域的图像。有没有办法检查两个图像之间的非透明区域是否发生碰撞?

谢谢。

(更新)所以这就是我到目前为止,不幸的是它仍然不能工作,但我不知道为什么。

if (!CGRectIntersectsRect(frame1, frame2)) return NO;
NSLog(@"OverlapsPixelsInImage:withImage:> Images Intersect");
UIImage *img1 = imgView1.image;
UIImage *img2 = imgView2.image;
CGImageRef imgRef1 = [img1 CGImage];
CGImageRef imgRef2 = [img2 CGImage];
float minx = MIN(frame1.origin.x, frame2.origin.x);
float miny = MIN(frame1.origin.y, frame2.origin.y);
float maxx = MAX(frame1.origin.x + frame1.size.width, frame2.origin.x + frame2.size.width);
float maxy = MAX(frame1.origin.y + frame1.size.height, frame2.origin.y + frame2.size.height);
CGRect canvasRect = CGRectMake(0, 0, maxx - minx, maxy - miny);
size_t width = floorf(canvasRect.size.width);
size_t height = floorf(canvasRect.size.height);
NSUInteger bitsPerComponent = 8;
NSUInteger bytesPerRow = 4 * width;
unsigned char *rawData = calloc(width * height, sizeof(*rawData));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(context, 0, canvasRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextClipToMask(context, CGRectMake(frame2.origin.x - minx, frame2.origin.y - miny, frame2.size.width, frame2.size.height), imgRef2);
CGContextDrawImage(context, CGRectMake(frame1.origin.x - minx, frame1.origin.y - miny, frame1.size.width, frame1.size.height), imgRef1);
CGContextRelease(context);
int byteIndex = 0;
for (int i = 0; i < width * height; i++)
{
    CGFloat alpha = rawData[byteIndex + 3];
    if (alpha > 128) 
    {
        NSLog(@"collided in byte: %d", i);
        free(rawData);
        return YES;
    }
    byteIndex += 4;
}
free(rawData);
return NO;

您可以将两个图像的alpha通道都绘制到单个位图上下文中,然后查看数据中的任何透明像素。看看剪辑CGRect到CGPath中的clipRectToPath()代码。这是在解决不同的问题,但方法是一样的。而不是使用CGContextFillPath()来绘制上下文,只需绘制您的两个图像。

流程如下:

  1. 创建一个纯alpha位图上下文(kCGImageAlphaOnly)
  2. 绘制你想要比较的所有内容
  3. 遍历像素,查看值。在我的例子中,它认为< 128是"透明的"。如果你想要完全透明,使用== 0
  4. 当您找到一个透明像素时,该示例只是记录它所在的列。在您的问题中,您可能只是返回YES,或者您可以使用该数据形成另一个掩码。

不容易,你基本上必须读取原始位图数据并遍历像素。

最新更新