2011-04-15 15 views
5

En mi aplicación, estoy capturando imágenes usando la cámara. Estos se almacenan en un NSArray como una representación NSData. Cuando vuelvo a convertir NSData a la imagen, ahora la orientación es horizontal en lugar de vertical como la tomé.Orientación de imagen de la cámara

NSData *data = UIImagePNGRepresentation([arrayImage objectAtIndex:0]); 
    UIImage *tmp = [UIImage imageWithData:data]; 

¿Alguien tiene una explicación? Gracias.

Respuesta

2

-[UIImage imageOrientation] podría ayudar :)

Orientación de la imagen afecta a la forma de visualización de los datos de imagen cuando se dibuja. Por defecto, las imágenes se muestran en la orientación "arriba". Sin embargo, si la imagen tiene metadatos asociados (como información EXIF), esta propiedad contiene la orientación indicada por esos metadatos. Para obtener una lista de posibles valores para esta propiedad, consulte “UIImageOrientation.”

Dado que la propiedad es de sólo lectura, y dependiendo de lo que quiere hacer, un posible (pero feo) solución podría ser:

UIImage *sourceImage = [arrayImage objectAtIndex:0]; 
NSData *data = UIImagePNGRepresentation(sourceImage); 
UIImage *tmp = [UIImage imageWithData:data]; 
UIImage *fixed = [UIImage imageWithCGImage:tmp.CGImage 
            scale:sourceImage.scale 
           orientation:sourceImage.imageOrientation]; 

(no probado y no puede/debe haber algo más limpio)

EDITAR: la primera parte fue una respuesta a su pregunta, una explicación más que una solución.

This y this(viejos?) entradas de blog podrían ser lecturas interesantes para usted. Extrañamente, nunca he conocido este problema mientras estoy usando UIImageJPEGRepresentation para enviar imágenes a un servidor ... ¿En qué versión de iOS estás trabajando? Eso podría ser un viejo error de SDK?

+0

bien que no resuelve el problema dentro de la aplicación. Sin embargo, no importa de qué manera oriente la imagen en la aplicación, cuando vuelvo a convertir a NSData para enviar la imagen en un correo electrónico, la imagen vuelve a los 90 grados CCW del original. Esto ciertamente parece un error? – DNewell

+0

respuesta editada con enlaces interesantes, la próxima vez publique una pregunta más detallada. –

2

Creo que esto es un error con el SDK. Me encontré con este problema exacto y luego cambié a UIImageJPEGRepresentation que solucionó el problema.

+0

¿Alguna confirmación sobre esto? Estoy teniendo el mismo problema y no puedo encontrar una solución para mi vida. Usar la representación JPEG está fuera de mi alcance ya que necesito la oferta de PNG de canal alfa. – Boeckm

+0

Esto me ayudó. He confirmado que el problema de orientación de la imagen no ocurre con la conversión JPEG –

14

que debe fijar la orientación de la imagen capturada por la cámara del código sigue, por defecto la orientación de la imagen de la cámara de no es correcto

- (UIImage *)fixrotation:(UIImage *)image 
{ 

    if (image.imageOrientation == UIImageOrientationUp) return image; 
    CGAffineTransform transform = CGAffineTransformIdentity; 

    switch (image.imageOrientation) { 
     case UIImageOrientationDown: 
     case UIImageOrientationDownMirrored: 
      transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height); 
      transform = CGAffineTransformRotate(transform, M_PI); 
      break; 

     case UIImageOrientationLeft: 
     case UIImageOrientationLeftMirrored: 
      transform = CGAffineTransformTranslate(transform, image.size.width, 0); 
      transform = CGAffineTransformRotate(transform, M_PI_2); 
      break; 

     case UIImageOrientationRight: 
     case UIImageOrientationRightMirrored: 
      transform = CGAffineTransformTranslate(transform, 0, image.size.height); 
      transform = CGAffineTransformRotate(transform, -M_PI_2); 
      break; 
     case UIImageOrientationUp: 
     case UIImageOrientationUpMirrored: 
      break; 
    } 

    switch (image.imageOrientation) { 
     case UIImageOrientationUpMirrored: 
     case UIImageOrientationDownMirrored: 
      transform = CGAffineTransformTranslate(transform, image.size.width, 0); 
      transform = CGAffineTransformScale(transform, -1, 1); 
      break; 

     case UIImageOrientationLeftMirrored: 
     case UIImageOrientationRightMirrored: 
      transform = CGAffineTransformTranslate(transform, image.size.height, 0); 
      transform = CGAffineTransformScale(transform, -1, 1); 
      break; 
     case UIImageOrientationUp: 
     case UIImageOrientationDown: 
     case UIImageOrientationLeft: 
     case UIImageOrientationRight: 
      break; 
    } 

    // Now we draw the underlying CGImage into a new context, applying the transform 
    // calculated above. 
    CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height, 
              CGImageGetBitsPerComponent(image.CGImage), 0, 
              CGImageGetColorSpace(image.CGImage), 
              CGImageGetBitmapInfo(image.CGImage)); 
    CGContextConcatCTM(ctx, transform); 
    switch (image.imageOrientation) { 
     case UIImageOrientationLeft: 
     case UIImageOrientationLeftMirrored: 
     case UIImageOrientationRight: 
     case UIImageOrientationRightMirrored: 
      // Grr... 
      CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage); 
      break; 

     default: 
      CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage); 
      break; 
    } 

    // And now we just create a new UIImage from the drawing context 
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 
    UIImage *img = [UIImage imageWithCGImage:cgimg]; 
    CGContextRelease(ctx); 
    CGImageRelease(cgimg); 
    return img; 
} 
+0

La orientación es correcta. Es incorrecta la lógica de algunos desarrolladores que no respetan los metadatos cuando transfieren o muestran la imagen. –

+0

esto resuelve mi problema. thx – Bimawa

+0

eso es trabajo para mí. Gracias –

0
dispatch_async([self sessionQueue], ^{ 
     // Update the orientation on the still image output video connection before capturing. 
     [[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]]; 

     // Flash set to Auto for Still Capture 
     [AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]]; 

     // Capture a still image. 
     [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 

      if (imageDataSampleBuffer) 
      { 
       NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
       UIImage *image = [[UIImage alloc] initWithData:imageData]; 
       [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil]; 
      } 
     }]; 
    }); 

https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html

0
//iOS Swift 3 

func fixRotation(image: UIImage) -> UIImage 
    { 
     if (image.imageOrientation == .up) 
     { 
      return image 
     } 

     var transform: CGAffineTransform = .identity 

     switch image.imageOrientation { 
     case .down, .downMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: image.size.height) 
      transform = transform.rotated(by: .pi) 
     case .left, .leftMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: 0) 
      transform = transform.rotated(by: .pi/2) 
     case .right, .rightMirrored: 
      transform = transform.translatedBy(x: 0, y: image.size.height) 
      transform = transform.rotated(by: -(.pi/2)) 
     case .up, .upMirrored: 
      break 
     } 

     switch image.imageOrientation { 
     case .upMirrored, .downMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: 0) 
      transform = transform.scaledBy(x: -1, y: 1) 
     case .leftMirrored, .rightMirrored: 
      transform = transform.translatedBy(x: image.size.height, y: 0) 
      transform = transform.scaledBy(x: -1, y: 1) 
     case .up, .down, .left, .right: 
      break 
     } 

     // Now we draw the underlying CGImage into a new context, applying the transform 
     // calculated above. 

     let cgimage = image.cgImage 
     let bitsPerComponent = cgimage?.bitsPerComponent 
     let colorSpace = cgimage?.colorSpace 
     let bitmapInfo = cgimage?.bitmapInfo 

     let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: bitsPerComponent! , bytesPerRow: 0, space: colorSpace!, bitmapInfo: bitmapInfo!.rawValue) 

     ctx?.concatenate(transform) 

     switch image.imageOrientation { 
     case .left, .leftMirrored, .right, .rightMirrored: 
      // Grr... 
      ctx?.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width)) 
     default: 
      ctx?.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) 
     } 

     let cgimg: CGImage = ctx!.makeImage()! 
     let img = UIImage(cgImage: cgimg) 
     return img 
    } 
Cuestiones relacionadas