I am trying to do a pixel by pixel comparison of two UIImages and I need to retrieve the pixels that are different. Using this Generate hash from UIImage I found a way to generate a hash for a UIImage. Is there a way to compare the two hashes and retrieve the different pixels?
1 Answer
If you want to actually retrieve the difference, the hash cannot help you. You can use the hash to detect the likely presence of differences, but to get the actual differences, you have to use other techniques.
For example, to create a UIImage that consists of the difference between two images, see this accepted answer in which Cory Kilgor's illustrates the use of CGContextSetBlendMode with a blend mode of kCGBlendModeDifference:
+ (UIImage *) differenceOfImage:(UIImage *)top withImage:(UIImage *)bottom { CGImageRef topRef = [top CGImage]; CGImageRef bottomRef = [bottom CGImage]; // Dimensions CGRect bottomFrame = CGRectMake(0, 0, CGImageGetWidth(bottomRef), CGImageGetHeight(bottomRef)); CGRect topFrame = CGRectMake(0, 0, CGImageGetWidth(topRef), CGImageGetHeight(topRef)); CGRect renderFrame = CGRectIntegral(CGRectUnion(bottomFrame, topFrame)); // Create context CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if(colorSpace == NULL) { printf("Error allocating color space.\n"); return NULL; } CGContextRef context = CGBitmapContextCreate(NULL, renderFrame.size.width, renderFrame.size.height, 8, renderFrame.size.width * 4, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); if(context == NULL) { printf("Context not created!\n"); return NULL; } // Draw images CGContextSetBlendMode(context, kCGBlendModeNormal); CGContextDrawImage(context, CGRectOffset(bottomFrame, -renderFrame.origin.x, -renderFrame.origin.y), bottomRef); CGContextSetBlendMode(context, kCGBlendModeDifference); CGContextDrawImage(context, CGRectOffset(topFrame, -renderFrame.origin.x, -renderFrame.origin.y), topRef); // Create image from context CGImageRef imageRef = CGBitmapContextCreateImage(context); UIImage * image = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); CGContextRelease(context); return image; } 2 Comments
user1802143
Thanks this works great for me. One issue I am having with this code is that it produces a black background. Is there a way to retain the same color scheme? In addition, rather than superimposing the differences is there a way to get two separate UIImages?
Rob
@user1802143 I'm not understanding your question, then. Generally when you talk about "difference", you're not looking to retrieve something that looks like one of the original images, but rather something that indicates the differences (where black means there was no difference, anything else is a difference). I'm not sure what "show me the difference but keep the same colors" possibly means. Perhaps you can more clearly articulate precisely how you expect this "difference" is to be captured/reported back to the user.