2011-10-22 13 views
1

私は、2つのUIImagesが非透明ピクセルだけを考慮して衝突するときを検出するメソッドをコーディングしようとしています。 UIImageViewのアルファ成分が0より大きいピクセルが、他のUIImageViewのアルファ成分が0より大きいピクセルと重なったときにTRUEを返すメソッド。2DピクセルレベルでのUIImage間の衝突検出

方法のようなものでなければなりません:

- (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; 

[UPDATE 2] 私はおそらくちょうどマスクされた画像を描画する前に必要な別の回線を使用しました。

CGContextSetBlendMode(context, kCGBlendModeCopy); 

まだ動作しません。奇妙なことに、私は衝突時に検出されたアルファ値をチェックしており、それらは乱数です。私が使用している画像は完全な不透明度または完全な透明度しか持たず、その間に何もないので、好奇心が強いです。

答えて

0

実際のフレーム交差点を確認してください - >あなたに長方形を与えます。 矩形内の画像のすべてのピクセルをアルファ> 0でチェックします。そうであれば、現在の座標を他のイメージに変換し、そのピクセルのアルファが0を超えるとヒットします。長方形が終わるまで繰り返す。 ヒットした場合は早期に停止してください。

+0

コードでこれを行う方法を知っていますか? – jglievano

0

ええと...あなたの画像の背後に白い四角があり、白いボックスを衝突させたくないという問題がありますが、その中の画像を衝突させたいのですか?まあ... 色に基づいて衝突をチェックできるとは思いません。あなたがする必要があるのは、(gimpのような)画像編集ソフトウェアをダウンロードし、白い背景を切り取ることです。