【问题标题】:ImageView rotating when using imagePicker使用 imagePicker 时 ImageView 旋转
【发布时间】:2016-07-01 07:46:37
【问题描述】:

我有一个表格视图,在单元格中,有一个图像和 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

}

这是didFinishPickingImage的函数:

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

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

谢谢

【问题讨论】:

    标签: ios swift iphone xcode uikit


    【解决方案1】:

    更新到 Swift 5.3、iOS 14

    Sunil Sharma 的solution 为我工作。这是 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
        }
    }
    

    【讨论】:

    • 您问自己的那些实例之一?为什么这是必要的... Anway,只需将复制粘贴到我的 swiftui 项目中并像魅力一样工作。谢谢
    【解决方案2】:

    UIImage 包含一个名为 imageOrientation 的属性。正如 Apple 文档中描述的该属性:

    图像方向会影响图像数据的显示方式 画。默认情况下,图像以“向上”方向显示。如果 图像具有关联的元数据(例如 EXIF 信息),但是, 此属性包含该元数据指示的方向。

    所以这个属性用来反映相机相对于地面的位置。所以当你从手机相机拍摄图像时,它会将方向标志保存在UIImageimageOrientation属性中。
    在显示时,如果忽略此属性,则您可能找不到正确方向的图像。仅供参考,请参阅下面的图像,相机如何拍摄图像,然后编码和显示。请查看此link 了解更多详细信息。

    在 ios 中解决这个问题
    Objective-C

    制作类别

    UIImage+fixOrientation.h

    @interface UIImage (fixOrientation)
    
    - (UIImage *)fixOrientation;
    
    @end
    

    UIImage+fixOrientation.m

    @implementation UIImage (fixOrientation)
    
    - (UIImage *)fixOrientation {
    
        // No-op if the orientation is already correct
        if (self.imageOrientation == UIImageOrientationUp) return self;
    
        // 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 (self.imageOrientation) {
            case UIImageOrientationDown:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
    
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                transform = CGAffineTransformRotate(transform, M_PI_2);
                break;
    
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, 0, self.size.height);
                transform = CGAffineTransformRotate(transform, -M_PI_2);
                break;
            case UIImageOrientationUp:
            case UIImageOrientationUpMirrored:
                break;
        }
    
        switch (self.imageOrientation) {
            case UIImageOrientationUpMirrored:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
                break;
    
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, self.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, self.size.width, self.size.height,
                                                 CGImageGetBitsPerComponent(self.CGImage), 0,
                                                 CGImageGetColorSpace(self.CGImage),
                                                 CGImageGetBitmapInfo(self.CGImage));
        CGContextConcatCTM(ctx, transform);
        switch (self.imageOrientation) {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                // Grr...
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
                break;
    
            default:
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.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;
    }
    
    @end
    

    斯威夫特

    将扩展设为

    extension UIImage {
    
        func fixOrientation() -> UIImage {
    
            // No-op if the orientation is already correct
            if ( self.imageOrientation == UIImageOrientation.Up ) {
                return self;
            }
    
            // 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 = CGAffineTransformIdentity
    
            if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
                transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
            }
    
            if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
                transform = CGAffineTransformTranslate(transform, self.size.width, 0)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
            }
    
            if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
                transform = CGAffineTransformTranslate(transform, 0, self.size.height);
                transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));
            }
    
            if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
                transform = CGAffineTransformTranslate(transform, self.size.width, 0)
                transform = CGAffineTransformScale(transform, -1, 1)
            }
    
            if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
                transform = CGAffineTransformTranslate(transform, self.size.height, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
            }
    
            // Now we draw the underlying CGImage into a new context, applying the transform
            // calculated above.
            let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
                                                          CGImageGetBitsPerComponent(self.CGImage), 0,
                                                          CGImageGetColorSpace(self.CGImage),
                                                          CGImageGetBitmapInfo(self.CGImage).rawValue)!;
    
            CGContextConcatCTM(ctx, transform)
    
            if ( self.imageOrientation == UIImageOrientation.Left ||
                self.imageOrientation == UIImageOrientation.LeftMirrored ||
                self.imageOrientation == UIImageOrientation.Right ||
                self.imageOrientation == UIImageOrientation.RightMirrored ) {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
            } else {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
            }
    
            // And now we just create a new UIImage from the drawing context and return it
            return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以像这篇文章一样旋转图像: https://stackoverflow.com/a/1317194/3928412

      你还需要获取设备旋转,你可以像这样得到它:

       UIDevice.currentDevice().orientation
      

      【讨论】:

        猜你喜欢
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多