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

发布于 2024-12-10 22:01:14 字数 1927 浏览 0 评论 0原文

我有两个 UIImageView,其中包含具有某些透明区域的图像。有什么方法可以检查两个图像之间的非透明区域是否发生碰撞?

谢谢。

[更新] 这就是我到目前为止所拥有的,不幸的是它仍然不起作用,但我不明白为什么。

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;

I have two UIImageViews that contain images with some transparent area. Is there any way to check if the non-transparent area between both images collide?

Thanks.

[UPDATE]
So this is what I have up until now, unfortunately it still ain't working but I can't figure out why.

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终难遇 2024-12-17 22:01:14

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

流程如下:

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

You can draw both the alpha channels of both images into a single bitmap context and then look through the data for any transparent pixels. Take a look at the clipRectToPath() code in Clipping CGRect to a CGPath. It's solving a different problem, but the approach is the same. Rather than using CGContextFillPath() to draw into the context, just draw both of your images.

Here's the flow:

  1. Create an alpha-only bitmap context (kCGImageAlphaOnly)
  2. Draw everything you want to compare into it
  3. Walk the pixels looking at the value. In my example, it considers < 128 to be "transparent." If you want fully transparent, use == 0.
  4. When you find a transparent pixel, the example just makes a note of what column it was in. In your problem, you might just return YES, or you might use that data to form another mask.
染年凉城似染瑾 2024-12-17 22:01:14

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

Not easily, you basically have to read the in raw bitmap data and walk the pixels.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文