2011-10-22 45 views
1

我試圖編碼一種方法,它可以檢測到兩個UIImages碰撞時只考慮非透明像素。只需要清楚,當UIImageView中alpha成分大於0的像素與其他UIImageView上的alpha成分大於0的像素重疊時,該方法返回TRUE。UIImages之間的2D像素級碰撞檢測

的方法應該是這樣的:

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

所以它接收兩個圖像進行檢查與它的框架獨立過去了座標位置必須轉換爲匹配(UIImageView.frame不會做)。

[UPDATE 1] 我將用我在上一個問題中使用的一段代碼進行更新,但是此代碼並不總是有效。我想問題在於所使用的UIImage不一定在同一個超級視圖中。

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; 

[UPDATE 2] 我只繪製掩蔽圖像之前使用據稱需要另一條線。

CGContextSetBlendMode(context, kCGBlendModeCopy); 

仍然不起作用。奇怪的是,我一直在檢查碰撞時檢測到的alpha值,它們是隨機數。它很好奇,因爲我使用的圖像只有完全不透明或完全透明,兩者之間沒有任何內容。

回答

0

檢查實際的框架交叉口 - >給你一個矩形。 檢查矩形中一個圖像中的每個像素的alpha> 0.如果是,則將當前座標轉換爲另一個圖像,然後如果該像素的alpha值大於0,那麼您有一個命中。重複,直到矩形完成。 如果你受到重創,請儘早停下來。

+0

你知道如何在代碼中做到這一點嗎? – jglievano

0

Hrmm ...你的問題是你的圖像背後有白色方塊,你不想讓白色方塊碰撞,但你想讓它們裏面的圖像碰撞?那麼... 我不認爲你可以根據顏色檢查碰撞。你需要做的是下載一些圖像編輯軟件(如gimp)並剪出白色背景。