Comparando UIImage

¿Cómo puedo comparar una imagen con otra?

¡Gracias!

Si tiene dos UIImages, debería obtener sus representaciones de cuarzo CGImageRef de esos objetos. A continuación, cree dos nuevos contextos de bitmap respaldados por un búfer de memoria que cree y pase, uno para cada una de las imágenes. Luego use CGContextDrawImage para dibujar las imágenes en los contextos del bitmap. Ahora los bytes de las imágenes están en los buffers. Luego puede recorrerlo manualmente o memcmp para verificar las diferencias.

La explicación detallada de Apple y el código de muestra para crear contextos de mapas de bits y dibujar en ellos está aquí:

https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html

La diferencia para usted es que está dibujando una imagen existente en el contexto. Use CGContextDrawImage para esto.

Esto es lo que uso en mis pruebas unitarias para comparar imágenes. A diferencia de otros métodos (p. Ej., UIImagePNGRepresentation ), funciona incluso si las imágenes tienen un espacio de color diferente (por ejemplo, RGB y escala de grises).

 @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 

No es muy eficiente, por lo que recomendaría no usarlo en el código de producción a menos que el rendimiento no sea un problema.

muestra del código aquí

 -(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