2011-02-14 15 views
10

Estoy usando UIImagePickerController para capturar una imagen y luego almacenarla. Sin embargo, cuando intento reescalarlo, el valor de orientación que obtengo de esta imagen es incorrecto. Cuando tomo un chasquido manteniendo el teléfono hacia arriba, me da orientación de izquierda. ¿Alguien ha experimentado este problema?UIImagePickerController devuelve una orientación de imagen incorrecta

el diccionario UIImagePickerController espectáculos siguiente información:

{ 
    UIImagePickerControllerMediaMetadata =  { 
     DPIHeight = 72; 
     DPIWidth = 72; 
     Orientation = 3; 
     "{Exif}" =   { 
      ApertureValue = "2.970853654340484"; 
      ColorSpace = 1; 
      DateTimeDigitized = "2011:02:14 10:26:17"; 
      DateTimeOriginal = "2011:02:14 10:26:17"; 
      ExposureMode = 0; 
      ExposureProgram = 2; 
      ExposureTime = "0.06666666666666667"; 
      FNumber = "2.8"; 
      Flash = 32; 
      FocalLength = "3.85"; 
      ISOSpeedRatings =    (
       125 
      ); 
      MeteringMode = 1; 
      PixelXDimension = 2048; 
      PixelYDimension = 1536; 
      SceneType = 1; 
      SensingMethod = 2; 
      Sharpness = 1; 
      ShutterSpeedValue = "3.910431673351467"; 
      SubjectArea =    (
       1023, 
       767, 
       614, 
       614 
      ); 
      WhiteBalance = 0; 
     }; 
     "{TIFF}" =   { 
      DateTime = "2011:02:14 10:26:17"; 
      Make = Apple; 
      Model = "iPhone 3GS"; 
      Software = "4.2.1"; 
      XResolution = 72; 
      YResolution = 72; 
     }; 
    }; 
    UIImagePickerControllerMediaType = "public.image"; 
    UIImagePickerControllerOriginalImage = "<UIImage: 0x40efb50>"; 
} 

No obstante imagen vuelva imageOrientation == 1;

UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];    

Respuesta

14

Acabo de empezar a trabajar en este tema en mi propia aplicación.

Utilicé la categoría UIImage que Trevor Harmon diseñó para cambiar el tamaño de una imagen y fijar su orientación, UIImage+Resize.

A continuación, puede hacer algo como esto en -imagePickerController:didFinishPickingMediaWithInfo:

 
UIImage *pickedImage = [info objectForKey:UIImagePickerControllerEditedImage]; 
UIImage *resized = [pickedImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit bounds:pickedImage.size interpolationQuality:kCGInterpolationHigh]; 

Esto solucionó el problema para mí. La imagen redimensionada está orientada correctamente visualmente y la propiedad imageOrientation informa UIImageOrientationUp.

Existen varias versiones de este código de escala/cambio de tamaño/recorte; Utilicé Trevor porque parece bastante limpio e incluye algunos otros manipuladores de UIImage que quiero usar más adelante.

+0

Esto no parece funcionar con el código compatible con ARC. Falla con el error: "No hay interfaz @ visible para 'UIImage' declara el selector 'resizedImageWithContentMode: bounds: interpolationQuality:'" – mpemburn

+0

Puede consultar un fork más actualizado de este código mantenido por Marc Charbonneau en GitHub.

+0

Incluso usando el tenedor de Marc, esto todavía no arregla la orientación. – Will

8

Esto es lo que encontré para solucionar problemas de orientación; Que funciona para mí

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 
NSData *data = UIImagePNGRepresentation(self.initialImage); 

UIImage *tempImage = [UIImage imageWithData:data]; 
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage 
            scale:initialImage.scale 
           orientation:self.initialImage.imageOrientation]; 
initialImage = fixedOrientationImage; 
+0

esto te dará. Recibió una advertencia de memoria. – Omarj

+0

¡Gracias, esto lo solucionó! – Flappy

0

Puedo usar el siguiente código que he puesto en un fichero objeto utilidad de imagen independiente que tiene un montón de otros métodos de edición para UIImages:

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(CGSize)targetSize 
{ 
    CGSize imageSize = sourceImage.size; 
    CGFloat width = imageSize.width; 
    CGFloat height = imageSize.height; 
    CGFloat targetWidth = targetSize.width; 
    CGFloat targetHeight = targetSize.height; 
    CGFloat scaleFactor = 0.0; 
    CGFloat scaledWidth = targetWidth; 
    CGFloat scaledHeight = targetHeight; 
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) { 
     CGFloat widthFactor = targetWidth/width; 
     CGFloat heightFactor = targetHeight/height; 

     if (widthFactor > heightFactor) { 
      scaleFactor = widthFactor; // scale to fit height 
     } 
     else { 
      scaleFactor = heightFactor; // scale to fit width 
     } 

     scaledWidth = width * scaleFactor; 
     scaledHeight = height * scaleFactor; 

     // center the image 
     if (widthFactor > heightFactor) { 
      thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
     } 
     else if (widthFactor < heightFactor) { 
      thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 
     } 
    } 

    CGImageRef imageRef = [sourceImage CGImage]; 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 

    if (bitmapInfo == kCGImageAlphaNone) { 
     bitmapInfo = kCGImageAlphaNoneSkipLast; 
    } 

    CGContextRef bitmap; 

    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { 
     bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } else { 
     bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } 

    // In the right or left cases, we need to switch scaledWidth and scaledHeight, 
    // and also the thumbnail point 
    if (sourceImage.imageOrientation == UIImageOrientationLeft) { 
     thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); 
     CGFloat oldScaledWidth = scaledWidth; 
     scaledWidth = scaledHeight; 
     scaledHeight = oldScaledWidth; 

     CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees 
     CGContextTranslateCTM (bitmap, 0, -targetHeight); 

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) { 
     thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); 
     CGFloat oldScaledWidth = scaledWidth; 
     scaledWidth = scaledHeight; 
     scaledHeight = oldScaledWidth; 

     CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees 
     CGContextTranslateCTM (bitmap, -targetWidth, 0); 

    } else if (sourceImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (sourceImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, targetWidth, targetHeight); 
     CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees 
    } 

    CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage* newImage = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return newImage; 
} 

Y entonces yo llamo

UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 
     UIImage *fixedOriginal = [ImageUtil imageWithImage:[mediaInfoDict objectForKey:UIImagePickerControllerOriginalImage] scaledToSizeWithSameAspectRatio:pickedImage.size]; 
4

He aquí un fragmento Swift que soluciona el problema de manera eficiente:

let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)! 
0

En iOS 7, necesitaba código dependiente de UIImage.imageOrientation para corregir las diferentes orientaciones. Ahora, en iOS 8.2, cuando selecciono mis viejas imágenes de prueba del álbum a través de UIImagePickerController, la orientación será UIImageOrientationUp para TODAS las imágenes. Cuando tomo una foto (UIImagePickerControllerSourceTypeCamera), esas imágenes también serán siempre hacia arriba, independientemente de la orientación del dispositivo. Entonces, entre esas versiones de iOS, obviamente ha habido una solución donde UIImagePickerController ya gira las imágenes si es necesario. Incluso puede observar que cuando se muestran las imágenes del álbum: por una fracción de segundo, se mostrarán en la orientación original, antes de que aparezcan en la nueva orientación hacia arriba.

Cuestiones relacionadas