【问题标题】:Detect pixel collision/overlapping between two images检测两个图像之间的像素碰撞/重叠
【发布时间】:2011-10-20 16:52:19
【问题描述】:

我有两个 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;

【问题讨论】:

    标签: iphone ios uiimageview transparency collision-detection


    【解决方案1】:

    您可以将两个图像的 Alpha 通道都绘制到一个位图上下文中,然后查看数据中是否有任何透明像素。查看Clipping CGRect to a CGPath 中的clipRectToPath() 代码。它解决了一个不同的问题,但方法是相同的。不要使用CGContextFillPath() 来绘制上下文,只需绘制两个图像即可。

    流程如下:

    1. 创建仅 alpha 位图上下文 (kCGImageAlphaOnly)
    2. 把所有你想比较的东西都画进去
    3. 查看像素值。在我的示例中,它认为&lt; 128 是“透明的”。如果您想要完全透明,请使用== 0
    4. 当您找到一个透明像素时,该示例只会记下它所在的列。在您的问题中,您可以只返回 YES,或者您可以使用该数据形成另一个掩码。

    【讨论】:

    • 我还不明白这个算法是如何检测碰撞的。对我来说很明显,如果我在 kCGImageAlphaOnly 上下文中绘制这两个图像,我会找到透明和不透明像素,因此寻找透明像素不会成功。
    • 你是对的。我不相信您可以在这里轻松地合并图像以找到重叠(我正在寻找透明度)。不过,@logancautrell 的方法应该可以正常工作。使用参考示例创建两个位图数组,然后遍历它们以查找X&gt;0 &amp;&amp; Y&gt;0
    • 也许你的方法也有效。您可以绘制一张图像来掩盖另一张图像。那么如果有任何不透明的像素就意味着有碰撞。
    • 我脑子里一直在思考这个问题,你应该是对的。我总是需要玩弄这些,然后在纸上勾勒出来,让它们在我的脑海中保持清晰。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多