Search code examples
ioshashpixel

iOS retrieve different pixels in pixel by pixel comparison of UIImages


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?


Solution

  • 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;
    }