ios ios8 photosframework

ios - Cómo obtener miniaturas cuadradas de PHImageManager?



ios8 photosframework (4)

Para obtener un cuadrado exacto, deberá indicar que desea un tamaño exacto pasando las opciones, de esta manera:

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; // No, really, we want this exact size options.resizeMode = PHImageRequestOptionsResizeModeExact [[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)_asset targetSize:CGSizeMake(160, 160) contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) { // Happily, result is now a squared image imageView.image = result; }];

¿Alguien ha pensado en cómo obtener los pulgares al cuadrado de PHImageManager? La opción PHImageContentModeAspectFill no tiene ningún efecto.

[[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)_asset targetSize:CGSizeMake(80, 80) contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info) { // sadly result is not a squared image imageView.image = result; }];


PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.resizeMode = PHImageRequestOptionsResizeModeExact; NSInteger retinaMultiplier = [UIScreen mainScreen].scale; CGSize retinaSquare = CGSizeMake(imageView.bounds.size.width * retinaMultiplier, imageView.bounds.size.height * retinaMultiplier); [[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)_asset targetSize:retinaSquare contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) { imageView.image =[UIImage imageWithCGImage:result.CGImage scale:retinaMultiplier orientation:result.imageOrientation]; }];


Esto está funcionando bien para mí:

__block UIImage* imgThumb; CGSize size=CGSizeMake(45, 45);// Size for Square image [self.imageManager requestImageForAsset:<your_current_phAsset> targetSize:size contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info) { imgThumb = result; }];


Actualizar:

El error al recortar las imágenes tal como se recuperaron de PHImageManager se corrigió en iOS 8.3, por lo que para esa versión de iOS y posterior, mi ejemplo original funciona de la siguiente manera: parece que los errores aún existen, incluido iOS 8.4, puedo reprodúzcalos con imágenes estándar de la cámara posterior del iPhone 6s, tomando una cosecha cuadrada de tamaño completo. Están corregidos en iOS 9.0, donde incluso los grandes cultivos de un panorama de 63 megapíxeles funcionan bien.

El enfoque que Apple define es pasar un CGRect en el espacio de coordenadas de la imagen, donde el origen es (0,0) y el máximo es (1,1). PHImageRequestOptions este rect en el objeto PHImageRequestOptions , junto con un resizeMode de PHImageRequestOptionsResizeModeExact , y luego debe recuperar una imagen recortada.

- (void)showSquareImageForAsset:(PHAsset *)asset { NSInteger retinaScale = [UIScreen mainScreen].scale; CGSize retinaSquare = CGSizeMake(100*retinaScale, 100*retinaScale); PHImageRequestOptions *cropToSquare = [[PHImageRequestOptions alloc] init]; cropToSquare.resizeMode = PHImageRequestOptionsResizeModeExact; CGFloat cropSideLength = MIN(asset.pixelWidth, asset.pixelHeight); CGRect square = CGRectMake(0, 0, cropSideLength, cropSideLength); CGRect cropRect = CGRectApplyAffineTransform(square, CGAffineTransformMakeScale(1.0 / asset.pixelWidth, 1.0 / asset.pixelHeight)); cropToSquare.normalizedCropRect = cropRect; [[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)asset targetSize:retinaSquare contentMode:PHImageContentModeAspectFit options:cropToSquare resultHandler:^(UIImage *result, NSDictionary *info) { self.imageView.image = result; }]; }

Este ejemplo hace que su cropRect de longitud lateral sea igual al menor del ancho y alto del activo, y luego lo transforma en el espacio de coordenadas de la imagen usando CGRectApplyAffineTransform . Es posible que desee establecer el origen del square en algo que no sea (0,0), con la frecuencia que desee que el cuadrado de recorte se centre en el eje de la imagen que se está recortando, pero lo dejaré como un ejercicio para el lector . :-)

Respuesta Original:

La respuesta de John me llevó la mayor parte del camino hasta allí, pero usando su código me estaba estirando y aplastando las imágenes. Así es como obtuve un imageView para mostrar miniaturas cuadradas obtenidas de PHImageManager.

En primer lugar, asegúrese de que la propiedad UIImageView para su UIImageView esté configurada en ScaleAspectFill . El valor predeterminado es ScaleToFill , que no funciona correctamente para mostrar miniaturas cuadradas de PHImageManager , así que asegúrese de cambiar esto si ha UIImageView instancia de UIImageView en el código o en el guión gráfico.

//view dimensions are based on points, but we''re requesting pixels from PHImageManager NSInteger retinaMultiplier = [UIScreen mainScreen].scale; CGSize retinaSquare = CGSizeMake(imageView.bounds.size.width * retinaMultiplier, imageView.bounds.size.height * retinaMultiplier); [[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)_asset targetSize:retinaSquare contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info) { // The result is not square, but correctly displays as a square using AspectFill imageView.image = result; }];

resizeMode es necesario especificar PHImageRequestOptionsResizeModeExact para resizeMode , ya que no le proporcionará una imagen recortada a menos que también proporcione resizeMode normalizedCropRect , y no debe usarse aquí ya que no ofrece ningún beneficio, y al usarlo no obtendrá los beneficios de una devolución rápida. imágenes en caché.

El UIImage devuelto en el result tendrá la misma relación de aspecto que la fuente, pero se escalará correctamente para su uso en un UIImageView que se configura en relleno de aspecto para mostrarse como un cuadrado, por lo que si solo lo muestra, este es el camino a seguir . Si necesita recortar la imagen para imprimirla o exportarla fuera de la aplicación, esto no es lo que desea; busque el uso de normalizedCropRect para eso. (edit- ver abajo, por ejemplo, de lo que debería funcionar ...)

Excepto que esto también se asegura de que establezca el modo de contenido de UIImageView en UIViewContentModeScaleAspectFill y que configure clipsToBounds = YES en las siguientes 2 líneas:

imageView.contentMode=UIViewContentModeScaleAspectFill; imageView.clipsToBounds=YES;

Editar para agregar el ejemplo de uso de normalizedCropRect
ADVERTENCIA: esto no funciona, pero de acuerdo con la documentación de Apple .

El enfoque que Apple define es pasar un CGRect en el espacio de coordenadas de la imagen, donde el origen es (0,0) y el máximo es (1,1). PHImageRequestOptions este rect en el objeto PHImageRequestOptions , junto con un resizeMode de PHImageRequestOptionsResizeModeExact , y luego debe recuperar una imagen recortada. El problema es que no, vuelve como la relación de aspecto original y la imagen completa.

Comprobé que el recorte se creó correctamente en el espacio de coordenadas de la imagen y seguí las instrucciones para usar PHImageRequestOptionsResizeModeExact , pero al controlador de resultados todavía se le pasará una imagen en la relación de aspecto original. Esto parece ser un error en el marco, y cuando se soluciona, el siguiente código debería funcionar.

- (void)showSquareImageForAsset:(PHAsset *)asset { NSInteger retinaScale = [UIScreen mainScreen].scale; CGSize retinaSquare = CGSizeMake(100*retinaScale, 100*retinaScale); PHImageRequestOptions *cropToSquare = [[PHImageRequestOptions alloc] init]; cropToSquare.resizeMode = PHImageRequestOptionsResizeModeExact; CGFloat cropSideLength = MIN(asset.pixelWidth, asset.pixelHeight); CGRect square = CGRectMake(0, 0, cropSideLength, cropSideLength); CGRect cropRect = CGRectApplyAffineTransform(square, CGAffineTransformMakeScale(1.0 / asset.pixelWidth, 1.0 / asset.pixelHeight)); cropToSquare.normalizedCropRect = cropRect; [[PHImageManager defaultManager] requestImageForAsset:(PHAsset *)asset targetSize:retinaSquare contentMode:PHImageContentModeAspectFit options:cropToSquare resultHandler:^(UIImage *result, NSDictionary *info) { self.imageView.image = result; }]; }

Todo lo que puedo sugerir es que si tienes este problema, ¡ archiva un radar con Apple para solicitar que lo arreglen!