AVFoundation在预览中将图像的方向偏离90度,但在相机图像的方向上偏好

真正奇怪的事情正在发生,我试图使用AVFoundation捕捉图像,相机滚动图像似乎很好,但图像预览图像旋转了90度。

这是我用来捕捉图像的代码

AVCaptureConnection *videoConnection = nil; for (AVCaptureConnection *connection in stillImageOutput.connections) { for (AVCaptureInputPort *port in [connection inputPorts]) { if ([[port mediaType] isEqual:AVMediaTypeVideo] ) { videoConnection = connection; break; } } if (videoConnection) { break; } } //NSLog(@"about to request a capture from: %@", stillImageOutput); [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); if (exifAttachments) { // Do something with the attachments. //NSLog(@"attachements: %@", exifAttachments); } else { NSLog(@"no attachments"); } NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; UIImage *image = [[UIImage alloc] initWithData:imageData]; self.vImage.image = image; UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); }]; 

是的,当你在你的设备的纵向方向上捕捉图像,并在你的应用程序中使用该图像时,会发生这种情况,因为图像的默认方向是任何IOS设备中的横向,所以在从图库中选取图像后,需要更改图像的方向在你的应用程序。

我已经把代码来实现这一点

Objective-C代码

 - (UIImage *)fixOrientationOfImage:(UIImage *)image { // No-op if the orientation is already correct if (image.imageOrientation == UIImageOrientationUp) return image; // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 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; } 

SWIFT代码

 func fixOrientationOfImage(image: UIImage) -> UIImage? { if image.imageOrientation == .Up { return image } // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. var transform = CGAffineTransformIdentity switch image.imageOrientation { case .Down, .DownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height) transform = CGAffineTransformRotate(transform, CGFloat(M_PI)) case .Left, .LeftMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0) transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2)) case .Right, .RightMirrored: transform = CGAffineTransformTranslate(transform, 0, image.size.height) transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2)) default: break } switch image.imageOrientation { case .UpMirrored, .DownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0) transform = CGAffineTransformScale(transform, -1, 1) case .LeftMirrored, .RightMirrored: transform = CGAffineTransformTranslate(transform, image.size.height, 0) transform = CGAffineTransformScale(transform, -1, 1) default: break } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. guard let context = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage).rawValue) else { return nil } CGContextConcatCTM(context, transform) switch image.imageOrientation { case .Left, .LeftMirrored, .Right, .RightMirrored: CGContextDrawImage(context, CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width), image.CGImage) default: CGContextDrawImage(context, CGRect(origin: .zero, size: image.size), image.CGImage) } // And now we just create a new UIImage from the drawing context guard let CGImage = CGBitmapContextCreateImage(context) else { return nil } return UIImage(CGImage: CGImage) } 

Swift 3.0

 func fixOrientationOfImage(image: UIImage) -> UIImage? { if image.imageOrientation == .up { return image } // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 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: CGFloat(Double.pi)) case .left, .leftMirrored: transform = transform.translatedBy(x: image.size.width, y: 0) transform = transform.rotated(by: CGFloat(Double.pi / 2)) case .right, .rightMirrored: transform = transform.translatedBy(x: 0, y: image.size.height) transform = transform.rotated(by: -CGFloat(Double.pi / 2)) default: 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) default: break } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. guard let context = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image.cgImage!.bitsPerComponent, bytesPerRow: 0, space: image.cgImage!.colorSpace!, bitmapInfo: image.cgImage!.bitmapInfo.rawValue) else { return nil } context.concatenate(transform) switch image.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width)) default: context.draw(image.cgImage!, in: CGRect(origin: .zero, size: image.size)) } // And now we just create a new UIImage from the drawing context guard let CGImage = context.makeImage() else { return nil } return UIImage(cgImage: CGImage) } 

被接受的答案是有效的,但是比需要的复杂得多。 您可以使用以下来旋转图像。

 - (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect { CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) { return deg / 180.0f * (CGFloat) M_PI; }; // determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position CGAffineTransform rectTransform; switch (image.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; // adjust the transformation scale based on the image scale rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale); // apply the transformation to the rect to create a new, shifted rect CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform); // use the rect to crop the image CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare); // create a new UIImage and set the scale and orientation appropriately UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; // memory cleanup CGImageRelease(imageRef); return result; } 

只是旋转图像,而不是裁剪,你可以简单地这样调用它:

 UIImage *image; [self cropImage:image toRect:rect.bounds];