相机图像的方向

在我的应用程序中,我使用相机捕捉图像。 这些被存储在NSArray作为一个NSData表示。 当我将NSData转换回图像时,现在的方向是横向而不是纵向。

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

任何人有一个解释? 谢谢。

您应该修复相机捕获的图像的方向,代码如下,默认情况下,相机图像的方向不正确

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

我认为这是SDK的一个错误。 我遇到了这个确切的问题,然后切换到解决问题的UIImageJPEGRepresentation。

– [UIImage imageOrientation]可能帮助:)

图像方向会影响绘制时图像数据的显示方式。 默认情况下,图像以“向上”的方向显示。 如果图像具有关联的元数据(例如EXIF信息),则此属性包含该元数据指示的方向。 有关此属性的可能值列表,请参阅“UIImageOrientation”。

既然这个属性是只读的,并且取决于你想要做什么,一个可能的(但是丑陋的)解决scheme可能是:

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

(未经testing,有可能/必须有更清洁的东西)

编辑 :第一部分是你的问题的答案, 解释不只是一个修复。

这和这 (旧?)博客文章可能是你的有趣读物。 奇怪的是,我从来没有遇到这个问题,而我正在使用UIImageJPEGRepresentation发送图像到服务器…你的工作是什么iOS版本? 这可能是一个旧的SDK错误?

 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

 //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 }