【问题标题】:2D Pixel-Level collision detection between UIImagesUIImages 之间的 2D 像素级碰撞检测
【发布时间】:2011-10-22 01:44:41
【问题描述】:

我正在尝试编写一种方法来检测两个 UIImage 何时发生碰撞,并仅考虑非透明像素。需要说明的是,当 UIImageView 上 alpha 分量大于 0 的像素与另一个 UIImageView 上 alpha 分量大于 0 的像素重叠时,该方法返回 TRUE。

方法应该是这样的:

- (void)checkCollisionBetweenImage:(UIImage *)img1 inFrame:(CGRect)frame1 andImage:(UIImage *)img2 inFrame:(CGRect)frame2;

因此它接收两个要检查的图像,并独立传递其帧,因为必须将坐标位置转换为匹配(UIImageView.frame 不会这样做)。

[更新 1] 我将使用我在上一个问题中使用的一段代码进行更新,但是这段代码并不总是有效。我想问题在于使用的 UIImages 不一定在同一个超级视图中。

Detect pixel collision/overlapping between two images

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 = malloc(canvasRect.size.width * canvasRect.size.height * 4 * bitsPerComponent);
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++)
{
    int8_t alpha = rawData[byteIndex + 3];
    if (alpha > 64) 
    {
        NSLog(@"collided in byte: %d", i);
        free(rawData);
        return YES;
    }
    byteIndex += 4;
}

free(rawData);

return NO;

[更新 2] 在绘制蒙版图像之前,我使用了据称需要的另一行。

CGContextSetBlendMode(context, kCGBlendModeCopy);

还是不行。奇怪的是,我一直在检查碰撞时检测到的 alpha 值,它们是随机数。这很奇怪,因为我使用的图像只有完全不透明或完全透明,两者之间没有任何关系。

【问题讨论】:

    标签: iphone objective-c uiimageview collision-detection


    【解决方案1】:

    检查实际的框架交叉点 -> 给你一个矩形。 检查矩形中一个图像中的每个像素的 alpha > 0。如果是这样,则将当前坐标转换为另一个图像的坐标,然后如果该像素的 alpha > 0,您就会成功。重复直到矩形完成。 如果您发现了热门歌曲,请尽早停止。

    【讨论】:

      【解决方案2】:

      嗯...您的问题是您的图像后面有白色方块并且您不希望白框发生碰撞,但您希望它们内部的图像发生碰撞?好... 我认为您不能根据颜色检查碰撞。您需要做的是下载一些图像编辑软件(如 gimp)并裁剪出白色背景。

      【讨论】:

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