使用 imagePicker 时 ImageView 旋转

Jas*_*onP 2 iphone xcode uikit ios swift

我有一个表格视图,在单元格中,有一个图像和 2 个标签。我正在使用imagePicker从我的相机胶卷中选择一张照片并将该照片放入单元格图像中。但是,当照片是人像模式照片时,图像会旋转 90 度。

在下面的代码中,posting 是一个连接到imageview表视图单元格中的插座,我初始化了一个UIImagePickerController.

class MakePostVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

@IBOutlet weak var postImg: UIImageView!
@IBOutlet weak var postTitle: UITextField!
@IBOutlet weak var postDescrip: UITextField!

var imgPicker: UIImagePickerController!

override func viewDidLoad() {
    super.viewDidLoad()

    postImg.layer.cornerRadius = 30
    postImg.clipsToBounds = true

    imgPicker = UIImagePickerController()
    imgPicker.delegate = self

}
Run Code Online (Sandbox Code Playgroud)

这是我的功能didFinishPickingImage

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
    imgPicker.dismissViewControllerAnimated(true, completion: nil)
    postImg.image = image
}
Run Code Online (Sandbox Code Playgroud)

我在 SO 上看过类似的帖子,但解决方案似乎不起作用。
有什么建议?

谢谢

Wit*_*ski 10

更新至 Swift 5.3、iOS 14

Sunil Sharma 的解决方案对我有用。这是Swift 5 的翻译版本

extension UIImage {
    var fixedOrientation: UIImage {
        guard imageOrientation != .up else { return self }
        
        var transform: CGAffineTransform = .identity
        switch imageOrientation {
        case .down, .downMirrored:
            transform = transform
                .translatedBy(x: size.width, y: size.height).rotated(by: .pi)
        case .left, .leftMirrored:
            transform = transform
                .translatedBy(x: size.width, y: 0).rotated(by: .pi)
        case .right, .rightMirrored:
            transform = transform
                .translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
        case .upMirrored:
            transform = transform
                .translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
        default:
            break
        }
        
        guard
            let cgImage = cgImage,
            let colorSpace = cgImage.colorSpace,
            let context = CGContext(
                data: nil, width: Int(size.width), height: Int(size.height),
                bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0,
                space: colorSpace, bitmapInfo: cgImage.bitmapInfo.rawValue
            )
        else { return self }
        context.concatenate(transform)
        
        var rect: CGRect
        switch imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            rect = CGRect(x: 0, y: 0, width: size.height, height: size.width)
        default:
            rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        }
        
        context.draw(cgImage, in: rect)
        return context.makeImage().map { UIImage(cgImage: $0) } ?? self
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您问自己的那些例子之一?为什么这是必要的......安威,只需复制粘贴到我的 swiftui 项目中,就可以正常工作了。谢谢 (2认同)

Sun*_*rma 6

UIImage包含一个名为 的属性imageOrientation。Apple 文档中描述了此属性:

\n\n
\n

图像方向影响绘制时图像数据的显示方式。默认情况下,图像以 \xe2\x80\x9cup\xe2\x80\x9d 方向显示。但是,如果图像具有关联的元数据(例如 EXIF 信息),则此属性包含该元数据指示的方向。

\n
\n\n

因此,此属性用于反映相机相对于地面的位置。因此,当您从手机相机拍摄图像时,它会在UIImage imageOrientation属性中保存方向标志。\n
在显示时,如果忽略此属性,则您可能找不到您的图像方向正确。仅供参考,请参阅下图,相机如何拍摄图像,然后进行编码和显示。查看此链接以了解更多详细信息。\n在此输入图像描述

\n\n

在 ios 中修复此问题
\n Objective-C

\n\n

制作类别

\n\n

UIImage+fixOrientation.h

\n\n
@interface UIImage (fixOrientation)\n\n- (UIImage *)fixOrientation;\n\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

UIImage+fixOrientation.m

\n\n
@implementation UIImage (fixOrientation)\n\n- (UIImage *)fixOrientation {\n\n    // No-op if the orientation is already correct\n    if (self.imageOrientation == UIImageOrientationUp) return self;\n\n    // We need to calculate the proper transformation to make the image upright.\n    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.\n    CGAffineTransform transform = CGAffineTransformIdentity;\n\n    switch (self.imageOrientation) {\n        case UIImageOrientationDown:\n        case UIImageOrientationDownMirrored:\n            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);\n            transform = CGAffineTransformRotate(transform, M_PI);\n            break;\n\n        case UIImageOrientationLeft:\n        case UIImageOrientationLeftMirrored:\n            transform = CGAffineTransformTranslate(transform, self.size.width, 0);\n            transform = CGAffineTransformRotate(transform, M_PI_2);\n            break;\n\n        case UIImageOrientationRight:\n        case UIImageOrientationRightMirrored:\n            transform = CGAffineTransformTranslate(transform, 0, self.size.height);\n            transform = CGAffineTransformRotate(transform, -M_PI_2);\n            break;\n        case UIImageOrientationUp:\n        case UIImageOrientationUpMirrored:\n            break;\n    }\n\n    switch (self.imageOrientation) {\n        case UIImageOrientationUpMirrored:\n        case UIImageOrientationDownMirrored:\n            transform = CGAffineTransformTranslate(transform, self.size.width, 0);\n            transform = CGAffineTransformScale(transform, -1, 1);\n            break;\n\n        case UIImageOrientationLeftMirrored:\n        case UIImageOrientationRightMirrored:\n            transform = CGAffineTransformTranslate(transform, self.size.height, 0);\n            transform = CGAffineTransformScale(transform, -1, 1);\n            break;\n        case UIImageOrientationUp:\n        case UIImageOrientationDown:\n        case UIImageOrientationLeft:\n        case UIImageOrientationRight:\n            break;\n    }\n\n    // Now we draw the underlying CGImage into a new context, applying the transform\n    // calculated above.\n    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,\n                                             CGImageGetBitsPerComponent(self.CGImage), 0,\n                                             CGImageGetColorSpace(self.CGImage),\n                                             CGImageGetBitmapInfo(self.CGImage));\n    CGContextConcatCTM(ctx, transform);\n    switch (self.imageOrientation) {\n        case UIImageOrientationLeft:\n        case UIImageOrientationLeftMirrored:\n        case UIImageOrientationRight:\n        case UIImageOrientationRightMirrored:\n            // Grr...\n            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);\n            break;\n\n        default:\n            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);\n            break;\n    }\n\n    // And now we just create a new UIImage from the drawing context\n    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);\n    UIImage *img = [UIImage imageWithCGImage:cgimg];\n    CGContextRelease(ctx);\n    CGImageRelease(cgimg);\n    return img;\n}\n\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

迅速

\n\n

将扩展名设置为

\n\n
extension UIImage {\n\n    func fixOrientation() -> UIImage {\n\n        // No-op if the orientation is already correct\n        if ( self.imageOrientation == UIImageOrientation.Up ) {\n            return self;\n        }\n\n        // We need to calculate the proper transformation to make the image upright.\n        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.\n        var transform: CGAffineTransform = CGAffineTransformIdentity\n\n        if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {\n            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)\n            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))\n        }\n\n        if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {\n            transform = CGAffineTransformTranslate(transform, self.size.width, 0)\n            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))\n        }\n\n        if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {\n            transform = CGAffineTransformTranslate(transform, 0, self.size.height);\n            transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));\n        }\n\n        if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {\n            transform = CGAffineTransformTranslate(transform, self.size.width, 0)\n            transform = CGAffineTransformScale(transform, -1, 1)\n        }\n\n        if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {\n            transform = CGAffineTransformTranslate(transform, self.size.height, 0);\n            transform = CGAffineTransformScale(transform, -1, 1);\n        }\n\n        // Now we draw the underlying CGImage into a new context, applying the transform\n        // calculated above.\n        let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),\n                                                      CGImageGetBitsPerComponent(self.CGImage), 0,\n                                                      CGImageGetColorSpace(self.CGImage),\n                                                      CGImageGetBitmapInfo(self.CGImage).rawValue)!;\n\n        CGContextConcatCTM(ctx, transform)\n\n        if ( self.imageOrientation == UIImageOrientation.Left ||\n            self.imageOrientation == UIImageOrientation.LeftMirrored ||\n            self.imageOrientation == UIImageOrientation.Right ||\n            self.imageOrientation == UIImageOrientation.RightMirrored ) {\n            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)\n        } else {\n            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)\n        }\n\n        // And now we just create a new UIImage from the drawing context and return it\n        return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n