Обнаружение столкновения / перекрытия пикселей между двумя изображениями - PullRequest
4 голосов
/ 20 октября 2011

У меня есть два UIImageViews, которые содержат изображения с некоторой прозрачной областью.Есть ли способ проверить, не сталкиваются ли непрозрачные области между обоими изображениями?

Спасибо.

[ОБНОВЛЕНИЕ] Так что это то, что у меня есть до сих пор, к сожалению, это все еще неработает, но я не могу понять, почему.

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;

Ответы [ 2 ]

1 голос
/ 20 октября 2011

Вы можете нарисовать оба альфа-канала обоих изображений в одном растровом контексте, а затем просмотреть данные на наличие прозрачных пикселей.Взгляните на код clipRectToPath() в Отсечение CGRect до CGPath .Это решает другую проблему, но подход тот же.Вместо того, чтобы использовать CGContextFillPath() для рисования в контексте, просто нарисуйте оба ваших изображения.

Вот поток:

  1. Создание альфа-контекста только для растровых изображений (kCGImageAlphaOnly)
  2. Нарисуйте в нем все, что хотите сравнить
  3. Пройдите по пикселям, глядя на значение.В моем примере он считает < 128 «прозрачным».Если вы хотите полностью прозрачный, используйте == 0.
  4. Когда вы найдете прозрачный пиксель, в примере просто запоминается, в каком столбце он был. В вашей задаче вы можете просто вернуть YES илиВы можете использовать эти данные для формирования другой маски.
1 голос
/ 20 октября 2011

Не легко, вам в основном приходится читать необработанные растровые данные и проходить пиксели.

...