Tamaño de image ALAsset

Dado un ALAsset que representa una foto, ¿es posible recuperar el tamaño de la foto (alto y ancho) sin cargar la image en una UIImageView y también sin usar el método aspectRationThumnail?

Solo una nota: iOS 5.1 introduce una nueva dimensión de propiedad para una instancia de ALAssetRepresentation. Esto devuelve una estructura CGSize con las dimensiones de la image original y podría ser la mejor solución para este problema en el futuro.

Aclamaciones,

Hendrik

 float width = asset.defaultRepresentation.dimensions.width; float height = asset.defaultRepresentation.dimensions.height; 

Es rápido, estable y da las dimensiones reales. Lo he usado con ALAsset de videos.

Una forma más simple de acceder al tamaño de la image es a través de [ALAssetRepresentation metadata] . En las imágenes que probé, este NSDictionary contenía keys denominadas PixelWidth y PixelHeight , que eran NSNumber objects con los valores que cabría esperar.

Sin embargo, parece que no existen garantías particulares sobre las keys exactas que encontrará, así que asegúrese de que su aplicación pueda ocuparse de los casos en que esas keys no están en los metadatos. También vea los metadatos de imágenes de iOS ALAsset para algunas precauciones sobre la velocidad y la security de los hilos.

Comparación

Probé ambos methods, cargando los datos de image en CGImageSourceRef o leyendo los metadatos, en la biblioteca de activos completa de mi iPad. Ambos methods devolvieron los mismos tamaños a FLT_EPSILON. Aparte de 2 valores atípicos que tomaron el doble de time, los times de ejecución de 16 repeticiones fueron muy similares:

 Método |  Tiempo medio +/- 95% de confianza
 Tamaño de CGImageSourceRef |  0.1787 +/- 0.0004
 Tamaño de los metadatos |  0.1789 +/- 0.0015

Entonces, ninguno de los dos methods tiene un beneficio de performance. Es completamente posible que el dictionary de metadatos se construya a pedido leyendo los datos de la image.

Actualizar

Esto no funcionó como se ofreció originalmente, como se señaló en los comentarios. Lo he solucionado, pero ahora carga todos los datos de image, que el OP intentaba evitar. Todavía evita el paso adicional, y aún peor, de descomprimir los datos en una image.

  1. Obtenga la presentación por defaultRepresentation del ALAsset.
  2. Obtenga los datos para el ALAssetRepresentation.
  3. Use una adaptación de esta útil function sizeOfImageAtURL . Gracias shpakovski

El código a continuación representa los pasos anteriores.

 // This method requires the ImageIO.framework // This requires memory for the size of the image in bytes, but does not decompress it. - (CGSize)sizeOfImageWithData:(NSData*) data; { CGSize imageSize = CGSizeZero; CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL); if (source) { NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCGImageSourceShouldCache]; NSDictionary *properties = (__bridge_transfer NSDictionary*) CGImageSourceCopyPropertiesAtIndex(source, 0, (__bridge CFDictionaryRef) options); if (properties) { NSNumber *width = [properties objectForKey:(NSString *)kCGImagePropertyPixelWidth]; NSNumber *height = [properties objectForKey:(NSString *)kCGImagePropertyPixelHeight]; if ((width != nil) && (height != nil)) imageSize = CGSizeMake(width.floatValue, height.floatValue); } CFRelease(source); } return imageSize; } - (CGSize)sizeOfAssetRepresentation:(ALAssetRepresentation*) assetRepresentation; { // It may be more efficient to read the [[[assetRepresentation] metadata] objectForKey:@"PixelWidth"] integerValue] and corresponding height instead. // Read all the bytes for the image into NSData. long long imageDataSize = [assetRepresentation size]; uint8_t* imageDataBytes = malloc(imageDataSize); [assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil]; NSData *data = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES]; return [self sizeOfImageWithData:data]; } - (CGSize)sizeOfAsset:(ALAsset*) asset; { return [self sizeOfAssetRepresentation:[asset defaultRepresentation]]; } 
 float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage); float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage); 

o igual para asset.defaultRepresentation.fullScreenImage