Subtract one image from another iOS

Does anyone know how to create a subtraction of one UIImage from another UIImage

for example, like this screen:

enter image description here

Thanks for the answer!

+9
ios objective-c uiimage
source share
5 answers

What does it mean to subtract the image? The above model image shows more operation! red. let's say that subtracting image a from image b means setting every pixel in b that intersects the pixel in transparent. in order to perform the subtraction, what we are actually doing is masking image b inverse to image a. so a good approach would be to create an image mask from the alpha channel of image a, and then apply it to b. to create a mask you will do something like this:

// 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); 

hmm. then, to mask image b, all you have to do is:

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

hey presto.

+4
source share

I believe you can do this using the kCGBlendModeDestinationOut blending kCGBlendModeDestinationOut . Create a new context, draw a background image, then draw a foreground image in this blend mode.

 UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, sourceImage.scale) [sourceImage drawAtPoint:CGPointZero]; [maskImage drawAtPoint:CGPointZero blendMode:kCGBlendModeDestinationOut alpha:1.0f]; UIImage *result = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); 
+13
source share

To get these results, use the second image as a mask when drawing the first image. For such a picture you will need to use Core Graphics, aka Quartz 2D. The 2D quartz programming guide has a section on Bitmaps and image masks that should tell you everything you need to know.

You are asking about UIImage objects, but to use Core Graphics you will need CGImages. This is not a problem - UIImage provides the CGImage property, which makes it easy to get the data you need.

+3
source share

Kevin Ballard's solution worked for me! In 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 } 
0
source share

Updated answer for iOS 10+ and 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
source share

All Articles