Based on aroth's idea, this is my full implementation. It checks if some random pixels are the same. For what I needed it works flawlessly.
- (bool)isTheImage:(UIImage *)image1 apparentlyEqualToImage:(UIImage *)image2 accordingToRandomPixelsPer1:(float)pixelsPer1
{
if (!CGSizeEqualToSize(image1.size, image2.size))
{
return false;
}
int pixelsWidth = CGImageGetWidth(image1.CGImage);
int pixelsHeight = CGImageGetHeight(image1.CGImage);
int pixelsToCompare = pixelsWidth * pixelsHeight * pixelsPer1;
uint32_t pixel1;
CGContextRef context1 = CGBitmapContextCreate(&pixel1, 1, 1, 8, 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
uint32_t pixel2;
CGContextRef context2 = CGBitmapContextCreate(&pixel2, 1, 1, 8, 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
bool isEqual = true;
for (int i = 0; i < pixelsToCompare; i++)
{
int pixelX = arc4random() % pixelsWidth;
int pixelY = arc4random() % pixelsHeight;
CGContextDrawImage(context1, CGRectMake(-pixelX, -pixelY, pixelsWidth, pixelsHeight), image1.CGImage);
CGContextDrawImage(context2, CGRectMake(-pixelX, -pixelY, pixelsWidth, pixelsHeight), image2.CGImage);
if (pixel1 != pixel2)
{
isEqual = false;
break;
}
}
CGContextRelease(context1);
CGContextRelease(context2);
return isEqual;
}
Usage:
[self isTheImage:image1 apparentlyEqualToImage:image2
accordingToRandomPixelsPer1:0.001]; // Use a value between 0.0001 and 0.005
According to my performance tests, 0.005 (0.5% of the pixels) is the maximum value you should use. If you need more precision, just compare the whole images
using this. 0.001 seems to be a safe and well-performing value. For large images (like between 0.5 and 2 megapixels or million pixels), I'm using 0.0001 (0.01%) and it works great and incredibly fast, it never makes a mistake.
But of course the mistake-ratio will depend on the type of images you are using. I'm using UIWebView screenshots and 0.0001 performs well, but you can probably use much less if you are comparing real photographs (even just compare one random pixel in fact). If you are dealing with very similar computer designed images you definitely need more precision.
Note: I'm always comparing ARGB images without taking into account the alpha channel. Maybe you'll need to adapt it if that's not exactly your case.