Вычесть одно изображение из другого iOS - PullRequest
9 голосов
/ 13 марта 2012

Кто-нибудь знает, как создать вычитание одного UIImage из другого UIImage

например как этот экран:

enter image description here

Спасибо за ответ!

Ответы [ 5 ]

13 голосов
/ 14 марта 2012

Я полагаю, что вы можете сделать это, используя режим наложения kCGBlendModeDestinationOut. Создайте новый контекст, нарисуйте фоновое изображение, затем нарисуйте изображение переднего плана в этом режиме наложения.

UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, sourceImage.scale)
[sourceImage drawAtPoint:CGPointZero];
[maskImage drawAtPoint:CGPointZero blendMode:kCGBlendModeDestinationOut alpha:1.0f];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
4 голосов
/ 14 марта 2012

что значит вычесть изображение?На приведенном примере показано больше операции! red.допустим, что вычитать изображение a из изображения b означает установить каждый пиксель в b, который пересекает пиксель в a, в прозрачный.чтобы выполнить вычитание, мы фактически маскируем изображение b к изображению a.Итак, хорошим подходом было бы создать маску изображения из альфа-канала изображения a, а затем применить ее к b.чтобы создать маску, вы должны сделать что-то вроде этого:

// get access to the image bytes
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));

// create a buffer to hold the mask values
size_t width = CGImageGetWidth(image.CGImage);
size_t height = CGImageGetHeight(image.CGImage);    
uint8_t *maskData = malloc(width * height);

// iterate over the pixel data, reading the alpha value
uint8_t *alpha = (uint8_t *)CFDataGetBytePtr(pixelData) + 3;
uint8_t *mask = maskData;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        *mask = *alpha;
        mask++;      
        alpha += 4;  // skip to the next pixel
    }
}

// create the mask image from the buffer
CGDataProviderRef maskProvider = CGDataProviderCreateWithData(NULL, maskData, width * height, NULL);
CGImageRef maskImage = CGImageMaskCreate(width, height, 8, 8, width, maskProvider, NULL, false);

// cleanup
CFRelease(pixelData);
CFRelease(maskProvider);
free(maskData);

Вот так.затем, чтобы замаскировать изображение b, все, что вам нужно сделать, это:

CGImageRef subtractedImage = CGImageCreateWithMask(b.CGImage, maskImage);

эй presto.

3 голосов
/ 14 марта 2012

Чтобы получить эти результаты, используйте второе изображение в качестве маски при рисовании первого изображения.Для этого типа рисования вам нужно использовать Core Graphics, также известный как Quartz 2D. Руководство по программированию Quartz 2D имеет раздел Растровые изображения и маски изображений , в котором должно быть сказано все, что вам нужно знать.

You 'Вы спрашиваете об объектах UIImage, но для использования Core Graphics вам понадобится CGImages.Это не проблема - UIImage предоставляет свойство CGImage, которое позволяет легко получать нужные данные.

0 голосов
/ 03 мая 2019

Обновленный ответ для iOS 10+ и Swift 4 +:

func subtract(source: UIImage, mask: UIImage) -> UIImage? {
    return UIGraphicsImageRenderer(size: source.size).image { _ in
        source.draw(at: .zero)
        mask.draw(at: .zero, blendMode: .destinationOut, alpha: 1)
    }
}
0 голосов
/ 22 июля 2017

Решение Кевина Балларда сработало для меня! В Swift 3.x:

func subtract(source: UIImage, mask: UIImage) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(source.size, false, source.scale)
    source.draw(at: CGPoint.zero)
    mask.draw(at: CGPoint.zero, blendMode: .destinationOut, alpha: 1.0)
    let result = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return result
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...