The correct answer depends on "What comparison do you want to do?".
- The easiest way is to simply compare the data.
- If you want to know if the image was created from one local file , you can use -isEqual: (but there is a dangerous way, because I'm not sure what will happen if the image cache is for some reason).
- The difficult way is to provide a pixel comparison (of course, the system will spend more time on it). I canβt provide the code from our corporate library for a legal reason :(
But you can check out a good example in the facebook ios-snapshot-test-case facebook project here: link directly to the file you need . You can use performance tests to measure process time.
For Great Justice, I will copy the code below:
- (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance { NSAssert(CGSizeEqualToSize(self.size, image.size), @"Images must be same size."); CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); // The images have the equal size, so we could use the smallest amount of bytes because of byte padding size_t minBytesPerRow = MIN(CGImageGetBytesPerRow(self.CGImage), CGImageGetBytesPerRow(image.CGImage)); size_t referenceImageSizeBytes = referenceImageSize.height * minBytesPerRow; void *referenceImagePixels = calloc(1, referenceImageSizeBytes); void *imagePixels = calloc(1, referenceImageSizeBytes); if (!referenceImagePixels || !imagePixels) { free(referenceImagePixels); free(imagePixels); return NO; } CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels, referenceImageSize.width, referenceImageSize.height, CGImageGetBitsPerComponent(self.CGImage), minBytesPerRow, CGImageGetColorSpace(self.CGImage), (CGBitmapInfo)kCGImageAlphaPremultipliedLast ); CGContextRef imageContext = CGBitmapContextCreate(imagePixels, imageSize.width, imageSize.height, CGImageGetBitsPerComponent(image.CGImage), minBytesPerRow, CGImageGetColorSpace(image.CGImage), (CGBitmapInfo)kCGImageAlphaPremultipliedLast ); if (!referenceImageContext || !imageContext) { CGContextRelease(referenceImageContext); CGContextRelease(imageContext); free(referenceImagePixels); free(imagePixels); return NO; } CGContextDrawImage(referenceImageContext, CGRectMake(0, 0, referenceImageSize.width, referenceImageSize.height), self.CGImage); CGContextDrawImage(imageContext, CGRectMake(0, 0, imageSize.width, imageSize.height), image.CGImage); CGContextRelease(referenceImageContext); CGContextRelease(imageContext); BOOL imageEqual = YES; // Do a fast compare if we can if (tolerance == 0) { imageEqual = (memcmp(referenceImagePixels, imagePixels, referenceImageSizeBytes) == 0); } else { // Go through each pixel in turn and see if it is different const NSInteger pixelCount = referenceImageSize.width * referenceImageSize.height; FBComparePixel *p1 = referenceImagePixels; FBComparePixel *p2 = imagePixels; NSInteger numDiffPixels = 0; for (int n = 0; n < pixelCount; ++n) { // If this pixel is different, increment the pixel diff count and see // if we have hit our limit. if (p1->raw != p2->raw) { numDiffPixels ++; CGFloat percent = (CGFloat)numDiffPixels / pixelCount; if (percent > tolerance) { imageEqual = NO; break; } } p1++; p2++; } } free(referenceImagePixels); free(imagePixels); return imageEqual; }
Vladlex Apr 20 '16 at 8:25 2016-04-20 08:25
source share