2011-04-15 113 views
5

在我的應用程序中,我使用相機捕捉圖像。這些被存儲在NSArray中作爲NSData表示。當我將NSData轉換回圖像時,方向現在是橫向而不是縱向,因爲我拿着它。相機圖像方向

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

任何人都有解釋嗎?謝謝。

回答

2

-[UIImage imageOrientation]可以幫助:)

形象定位影響時繪製顯示的圖像數據的方式。默認情況下,圖像以「向上」的方向顯示。但是,如果圖像具有關聯的元數據(如EXIF信息),則此屬性包含該元數據指示的方向。對於此屬性可能值的列表,請參閱「UIImageOrientation。」

由於該屬性是隻讀的,取決於你想要做什麼,可能(但醜陋的)的解決方案可能是:

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]; 

(未經測試,可能有/一定有什麼清潔劑)

編輯:第一部分是一個回答你的問題,解釋多一個修復程序。

Thisthis(舊?)博客文章可能是您感興趣的讀物。奇怪的是,我用UIImageJPEGRepresentation將圖像發送到服務器時,我從來沒有遇到過這個問題......你正在使用什麼iOS版本?這可能是一箇舊的SDK錯誤?

+0

那麼這根本解決問題內的應用程序。但是,當我將圖像轉換回NSData以便在電子郵件中發送圖像時,將圖像定向到應用程序的方式並不重要,圖像可以從原始圖像恢復到90度CCW。這當然看起來像一個錯誤? – DNewell 2011-04-17 21:25:50

+0

編輯回答有趣的鏈接,下次請發表更詳細的問題。 – 2011-04-17 22:30:24

2

我認爲這是SDK的錯誤。我遇到了這個確切的問題,然後切換到解決問題的UIImageJPEGRepresentation。

+0

對此有何確認?我遇到同樣的問題,無法找到解決我生活的問題。使用JPEG表示對於我來說不是問題,因爲我需要alpha通道PNG提供。 – Boeckm 2012-04-25 21:45:50

+0

這幫了我。我已確認JPEG轉換不會發生圖像方向問題 – 2015-10-03 02:34:11

14

你應該修改默認的攝像頭的代碼如下, 拍攝的圖像的取向攝像圖像的方向是不正確的

- (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

方向正確。不正確的是一些開發人員在傳輸或顯示圖像時不尊重元數據的邏輯。 – 2013-02-23 10:46:40

+0

這解決了我的麻煩。 thx – Bimawa 2014-02-26 09:37:52

+0

這對我有用。謝謝 – 2014-09-25 18:25:53

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 
    }