2012-01-04 12 views
5

Estoy tratando de comparar dos UIImages. Si se compara esta manera:Dos formas de comparar UIImages muestran resultados diferentes. ¿A cuál creer?

if ([UIImagePNGRepresentation (holderImage) isEqualToData:UIImagePNGRepresentation([UIImage imageNamed:@"empty_image.png"])]) 
      NSLog(@"empty image"); 
     else 
      NSLog(@"not empty image"); 

el resultado es Sí, son EQUAL

si estoy haciendo lo siguiente

` if ([holderImage isEqual:[UIImage imageNamed:@"empty_image.png"]]) 
      NSLog(@"empty image"); 
     else 
      NSLog(@"not empty image"); ` 

el resultado es No, no lo son

La situación es bastante complicada porque:

1) Las imágenes deben ser (eso significa que soy más o menos seguro) igual así que creería el primero a menos que

2) isEqual comparación siempre da resultado verdadero en otras imágenes.

Así que estoy completamente confundido. ¿Qué piensas sobre eso? Por cierto, el holderImage acaba de tomarse de NSUserDefaults. ¿Crees que podría ser cambiado de alguna manera mientras está almacenado en NSUserDefaults, por lo que la comparación de Equal está mintiendo ahora?

Respuesta

7

El método isEqual en UIImage parece un puntero/hash del objeto en tanto que el método isEqual en NSData se verá que los bytes son los mismos.

El isEqual utilizado por la mayoría de los objetos se basa en hash. En la documentación de Apple, se especifica que NSData implementa el método isEqual de una manera diferente.

Dos objetos de datos son iguales si tienen el mismo número de bytes y si los bytes en la misma posición en los objetos son los mismos.

+0

¿Seguro Por lo general, si lo comparo [myImage IsEqual:..? [UIImage imageNamed: @ "myImage.png"] ] (y SÉ que son iguales) la comparación dice que son iguales. ¿[UIImage imageNamed: @ "myImage.png"] tiene un puntero para ser comparado? –

+2

No, no estoy muy seguro, sino porque cuando ambas imágenes están cargadas a través del método 'imageNamed' se devuelve el mismo objeto porque' imageNamed' usa el almacenamiento en caché. – rckoenes

+1

@rckoenes Creo que la caché puede ser optimizada. Estábamos usando 'isEqual' y' imageNamed' en pruebas unitarias, y funciona muy bien en algunas situaciones, pero en otras devuelve NO cuando la comparación NSData pasa. –

4

PivotalCoreKit proporciona un helper para comparar las imágenes por bytes. Esto pasará si se crean las imágenes a través de diferentes fuentes (por ejemplo [UIImage -UIImageNamed] y [UIImage initWithData:], a diferencia de UIImagePNGRepresentation()

- (BOOL)isEqualToByBytes:(UIImage *)otherImage { 
    NSData *imagePixelsData = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage)); 
    NSData *otherImagePixelsData = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(otherImage.CGImage)); 

    BOOL comparison = [imagePixelsData isEqualToData:otherImagePixelsData]; 

    CGDataProviderRelease((CGDataProviderRef)imagePixelsData); 
    CGDataProviderRelease((CGDataProviderRef)otherImagePixelsData); 
    return comparison; 
} 
+0

También puede usar 'CFBridgingRelease': NSData * imagePixelsData = (NSData *) CFBridgingRelease (CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage))); ... De esta forma no es necesario liberar manualmente (CGDataProviderRelease), pero ARC se encarga de eso. –

Cuestiones relacionadas