iOS UIImagePickerController result image orientation after upload

后端 未结 20 1976
长发绾君心
长发绾君心 2020-11-22 00:44

I am testing my iPhone application on an iOS 3.1.3 iPhone. I am selecting/capturing an image using a UIImagePickerController:

UIImagePickerCont         


        
相关标签:
20条回答
  • 2020-11-22 01:07

    Solution for Swift 3.1 for orientation issue while capturing the image from Camera.

    I have updated the solution given by jake and Metal Heart

    UIImage extension

    //MARK:- Image Orientation fix
    
    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 = CGAffineTransform.identity
    
            if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: self.size.height)
                transform = transform.rotated(by: CGFloat(Double.pi))
            }
    
            if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: 0)
                transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
            }
    
            if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
                transform = transform.translatedBy(x: 0, y: self.size.height);
                transform = transform.rotated(by: CGFloat(-Double.pi / 2.0));
            }
    
            if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: 0)
                transform = transform.scaledBy(x: -1, y: 1)
            }
    
            if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
                transform = transform.translatedBy(x: self.size.height, y: 0);
                transform = transform.scaledBy(x: -1, y: 1);
            }
    
            // Now we draw the underlying CGImage into a new context, applying the transform
            // calculated above.
            let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                                          bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                                          space: self.cgImage!.colorSpace!,
                                                          bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;
    
            ctx.concatenate(transform)
    
            if ( self.imageOrientation == UIImageOrientation.left ||
                self.imageOrientation == UIImageOrientation.leftMirrored ||
                self.imageOrientation == UIImageOrientation.right ||
                self.imageOrientation == UIImageOrientation.rightMirrored ) {
                ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width))
            } else {
                ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height))
            }
    
            // And now we just create a new UIImage from the drawing context and return it
            return UIImage(cgImage: ctx.makeImage()!)
        }
    }
    

    Swift 2.0

    //MARK:- Image Orientation fix
    
    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)!)
        }
    }
    

    Use of this UIImage Extension in your code:

    let fixOrientationImage=chosenImage.fixOrientation()

    place this in your delegate methods of image picker like this

    Swift 3.1

    //MARK: Image Picker Delegates
        func imagePickerController(
            _ picker: UIImagePickerController,
            didFinishPickingMediaWithInfo info: [String : Any]){
            let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
            profileImg.contentMode = .scaleAspectFill
            let fixOrientationImage=chosenImage.fixOrientation()
            profileImg.image = fixOrientationImage
    
            dismiss(animated: true, completion: nil)
        }
    

    Swift 2.0

    //MARK: Image Picker Delegates
        func imagePickerController(
            picker: UIImagePickerController,
            didFinishPickingMediaWithInfo info: [String : AnyObject])
        {
            let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
            profileImg.contentMode = .ScaleAspectFill
            **//Fix the image orientation**
             let fixOrientationImage=chosenImage.fixOrientation()
            profileImg.image = fixOrientationImage
    
            dismissViewControllerAnimated(true, completion: nil)
        }
    
    0 讨论(0)
  • 2020-11-22 01:10

    Swift 3 version based on @jake1981 who've taken it from @MetalHeart2003

    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 = CGAffineTransform.identity
    
            if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: self.size.height)
                transform = transform.rotated(by: CGFloat(M_PI))
            }
    
            if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: 0)
                transform = transform.rotated(by: CGFloat(M_PI_2))
            }
    
            if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
                transform = transform.translatedBy(x: 0, y: self.size.height);
                transform = transform.rotated(by: CGFloat(-M_PI_2));
            }
    
            if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
                transform = transform.translatedBy(x: self.size.width, y: 0)
                transform = transform.scaledBy(x: -1, y: 1)
            }
    
            if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
                transform = transform.translatedBy(x: self.size.height, y: 0);
                transform = transform.scaledBy(x: -1, y: 1);
            }
    
            // Now we draw the underlying CGImage into a new context, applying the transform
            // calculated above.
            let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                           bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                           space: self.cgImage!.colorSpace!,
                                           bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!
            ctx.concatenate(transform)
    
            if ( self.imageOrientation == UIImageOrientation.left ||
                self.imageOrientation == UIImageOrientation.leftMirrored ||
                self.imageOrientation == UIImageOrientation.right ||
                self.imageOrientation == UIImageOrientation.rightMirrored ) {
    
                ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
            } else {
                ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
            }
    
            // And now we just create a new UIImage from the drawing context and return it
            return UIImage(cgImage: ctx.makeImage()!)
    
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:12

    If you enable editing, then the edited image (as opposed to the original) will be oriented as expected:

    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.allowsEditing = YES;
    // set delegate and present controller
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
        UIImage *photo = [info valueForKey:UIImagePickerControllerEditedImage];
        // do whatever
    }
    

    Enabling editing allows the user to resize and move the image before tapping "Use Photo"

    0 讨论(0)
  • 2020-11-22 01:13

    Here is an UIImage extension in Swift 2 based on the accepted answer by @Anomie. It uses a clearer switch case. It also takes the optional value returned by CGBitmapContextCreateImage() into consideration.

    extension UIImage {
        func rotateImageByOrientation() -> UIImage {
            // No-op if the orientation is already correct
            guard self.imageOrientation != .Up else {
                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 = CGAffineTransformIdentity;
    
            switch (self.imageOrientation) {
            case .Down, .DownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
    
            case .Left, .LeftMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
    
            case .Right, .RightMirrored:
                transform = CGAffineTransformTranslate(transform, 0, self.size.height)
                transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
    
            default:
                break
            }
    
            switch (self.imageOrientation) {
            case .UpMirrored, .DownMirrored:
                transform = CGAffineTransformTranslate(transform, self.size.width, 0)
                transform = CGAffineTransformScale(transform, -1, 1)
    
            case .LeftMirrored, .RightMirrored:
                transform = CGAffineTransformTranslate(transform, self.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.
            let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
                CGImageGetBitsPerComponent(self.CGImage), 0,
                CGImageGetColorSpace(self.CGImage),
                CGImageGetBitmapInfo(self.CGImage).rawValue)
            CGContextConcatCTM(ctx, transform)
            switch (self.imageOrientation) {
            case .Left, .LeftMirrored, .Right, .RightMirrored:
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
    
            default:
                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
            if let cgImage = CGBitmapContextCreateImage(ctx) {
                return UIImage(CGImage: cgImage)
            } else {
                return self
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:13

    I achieve this by writing below a few lines of code

    extension UIImage {
    
        public func correctlyOrientedImage() -> UIImage {
            guard imageOrientation != .up else { return self }
    
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            draw(in: CGRect(origin: .zero, size: size))
            let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
    
            return normalizedImage
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:14

    I transposed this into Xamarin:

    private static UIImage FixImageOrientation(UIImage image)
        {
            if (image.Orientation == UIImageOrientation.Up)
            {
                return image;
            }
    
            var transform = CGAffineTransform.MakeIdentity();
    
            float pi = (float)Math.PI;
    
            switch (image.Orientation)
            {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
                    transform = CGAffineTransform.Rotate(transform, pi);
                    break;
    
                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                    transform = CGAffineTransform.Rotate(transform, pi / 2);
                    break;
    
                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
                    transform = CGAffineTransform.Rotate(transform, -(pi / 2));
                    break;
            }
    
            switch (image.Orientation)
            {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                    transform = CGAffineTransform.Scale(transform, -1, 1);
                    break;
    
                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
                    transform = CGAffineTransform.Scale(transform, -1, 1);
                    break;
            }
    
            var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
                image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);
    
            ctx.ConcatCTM(transform);
    
            switch (image.Orientation)
            {
                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                    break;
    
                default:
                    ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                    break;
            }
    
            var cgimg = ctx.ToImage();
            var img = new UIImage(cgimg);
    
            ctx.Dispose();
            ctx = null;
            cgimg.Dispose();
            cgimg = null;
    
            return img;
        }
    
    0 讨论(0)
提交回复
热议问题