比较UIImage
我怎样才能比较一个图像到另一个?
谢谢!
如果你有两个UIImages,你应该从这些对象中获得它们的CGImageRef
石英表示。 然后创build两个新的位图上下文,由您创build并传入的内存缓冲区支持,每个图像一个。 然后使用CGContextDrawImage
将图像绘制到位图上下文中。 现在图像的字节在缓冲区中。 然后您可以通过手动或memcmp
循环来检查差异。
苹果公司自己的详细的解释和示例代码围绕创build位图上下文并绘制在这里:
你的区别在于你正在将现有的图像绘制到上下文中。 为此使用CGContextDrawImage
。
这是我使用我的unit testing来比较图像。 与其他方法(例如UIImagePNGRepresentation
)不同,即使图像具有不同的颜色空间(例如RGB和灰度),它也可以工作。
@implementation UIImage (HPIsEqualToImage) - (BOOL)hp_isEqualToImage:(UIImage*)image { NSData *data = [image hp_normalizedData]; NSData *originalData = [self hp_normalizedData]; return [originalData isEqualToData:data]; } - (NSData*)hp_normalizedData { const CGSize pixelSize = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale); UIGraphicsBeginImageContext(pixelSize); [self drawInRect:CGRectMake(0, 0, pixelSize.width, pixelSize.height)]; UIImage *drawnImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return UIImagePNGRepresentation(drawnImage); } @end
这不是很有效,所以我build议不要在生产代码中使用它,除非性能不是问题。
这里的代码示例
-(NSMutableArray*)getImageBinary:(UIImage*)ImageToCompare { int i = 0; int step = 4; CGContextRef context = NULL; CGColorSpaceRef colorSpace; //void * bitmapData; //int bitmapByteCount; int bitmapBytesPerRow; // Get image width, height. We'll use the entire image. size_t pixelsWide = CGImageGetWidth(ImageToCompare.CGImage); size_t pixelsHigh = CGImageGetHeight(ImageToCompare.CGImage); // Declare the number of bytes per row. Each pixel in the bitmap in this // example is represented by 4 bytes; 8 bits each of red, green, blue, and // alpha. bitmapBytesPerRow = (pixelsWide * 4); NSMutableArray *firstImagearray=[[NSMutableArray alloc]init]; //bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); // Use the generic RGB color space. colorSpace = CGColorSpaceCreateDeviceRGB(); if (colorSpace == NULL) { fprintf(stderr, "Error allocating color space\n"); return nil; } // Allocate memory for image data. This is the destination in memory // where any drawing to the bitmap context will be rendered. //bitmapData = malloc( bitmapByteCount ); // if (bitmapData == NULL) // { // fprintf (stderr, "Memory not allocated!"); // CGColorSpaceRelease( colorSpace ); // return NULL; // } // Create the bitmap context. We want pre-multiplied ARGB, 8-bits // per component. Regardless of what the source image format is // (CMYK, Grayscale, and so on) it will be converted over to the format // specified here by CGBitmapContextCreate. context = CGBitmapContextCreate (NULL, pixelsWide, pixelsHigh, 8, // bits per component bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst); if (context == NULL) { //free (bitmapData); fprintf (stderr, "Context not created!"); } CGRect rect = {{0,0},{pixelsWide, pixelsHigh}}; // // Draw the image to the bitmap context. Once we draw, the memory // allocated for the context for rendering will then contain the // raw image data in the specified color space. CGContextDrawImage(context, rect, ImageToCompare.CGImage); // Make sure and release colorspace before returning CGColorSpaceRelease( colorSpace ); /////********** size_t _width = CGImageGetWidth(ImageToCompare.CGImage); size_t _height = CGImageGetHeight(ImageToCompare.CGImage); unsigned char* data = CGBitmapContextGetData (context); if (data != NULL) { int max = _width * _height * 4; for (i = 0; i < max; i+=step) { [firstImagearray addObject:[NSNumber numberWithInt:data[i + 0]]]; [firstImagearray addObject:[NSNumber numberWithInt:data[i + 1]]]; [firstImagearray addObject:[NSNumber numberWithInt:data[i + 2]]]; [firstImagearray addObject:[NSNumber numberWithInt:data[i + 3]]]; } } if (context == NULL) // error creating context return nil; //if (data) { free(data); } if (context) { CGContextRelease(context); } return firstImagearray; } -(BOOL)Compare:(UIImage*)ImageToCompare secondImage:(UIImage*)secondImage { ImageToCompare=[ImageToCompare scaleToSize:CGSizeMake(self.appdelegate.ScreenWidth,self.appdelegate.ScreenHeigth)]; secondImage=[secondImage scaleToSize:CGSizeMake(self.appdelegate.ScreenWidth, self.appdelegate.ScreenHeigth)]; NSArray *first=[[NSArray alloc] initWithArray:(NSArray *)[self getImageBinary:ImageToCompare]]; NSArray *second=[[NSArray alloc] initWithArray:(NSArray *)[self getImageBinary:secondImage]]; for (int x=0; x<first.count; x++) { if ([((NSNumber*)[first objectAtIndex:x]) intValue] ==[((NSNumber*)[second objectAtIndex:x]) intValue]) { } else { return NO; } } return YES; }