2011-10-20 93 views
4

我有兩個包含具有某些透明區域的圖像的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; 

回答

1

您可以將兩個圖像的Alpha通道都繪製到單個位圖上下文中,然後查看透明像素的數據。看看Clipping CGRect to a CGPath中的clipRectToPath()代碼。它解決了一個不同的問題,但方法是一樣的。而不是使用CGContextFillPath()繪製到上下文中,只需繪製兩個圖像。

這裏的流量:

  1. 創建一個字母只位圖上下文(kCGImageAlphaOnly
  2. 畫要比較進去
  3. 走看值的像素的一切。在我的例子中,它認爲< 128是「透明的」。如果您想完全透明,請使用== 0
  4. 當您找到一個透明像素時,該示例只是記錄它所在的列。在您的問題中,您可能只需返回YES,或者您可以使用該數據形成另一個掩碼。
+0

我不明白這個算法是如何檢測碰撞的。很明顯,如果我在kCGImageAlphaOnly上下文中繪製兩張圖像,我會發現透明和不透明的像素,因此尋找透明像素不會起作用。 – jglievano

+0

你是對的。我不相信你可以很容易地在這裏合併圖像來找到重疊(我正在尋找透明度)。儘管如此,@ logancautrell的方法應該可以正常工作。使用參考示例創建兩個位圖數組,然後將它們分別尋找'X> 0 && Y> 0'。 –

+0

也許你的方法也適用。你可以繪製一張圖片來掩蓋另一張圖片。那麼如果有任何不透明的像素,那就意味着有碰撞。 – jglievano

1

不容易,你基本上讀取原始位圖數據,然後步行像素。