首页 文章

iOS UIImagePickerController上传后的结果图像方向

提问于
浏览
311

我在iOS 3.1.3 iPhone上测试我的iPhone应用程序 . 我正在使用 UIImagePickerController 选择/捕获图像:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];



- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    imageView.image = self.image;
    [self.navigationController dismissModalViewControllerAnimated:YES];
    submitButton.enabled = YES;
}

然后我在某个时候使用ASI类将它发送到我的Web服务器:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:@"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:@"image/jpg" forKey:@"imageFile"];
[request startAsynchronous];

问题:当我用iphone拍照同时保持它的风景时,图像会上传到服务器并且它会像你期望的那样被观看 . 当拍摄手机拍照时,图像会被上传并在旋转90度时被观看 .

我的应用程序设置为仅在纵向模式下工作(颠倒和常规) .

如何在上传后使图像始终显示正确的方向?

UIImageView中显示的图像看起来是正确的(在拍照后直接显示),但在服务器上查看则另有说明 .

15 回答

  • 24

    在迅速;)

    更新SWIFT 3.0:D

    func sFunc_imageFixOrientation(img:UIImage) -> UIImage {
    
    
        // No-op if the orientation is already correct
        if (img.imageOrientation == UIImageOrientation.up) {
            return img;
        }
        // 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 (img.imageOrientation == UIImageOrientation.down
            || img.imageOrientation == UIImageOrientation.downMirrored) {
    
            transform = transform.translatedBy(x: img.size.width, y: img.size.height)
            transform = transform.rotated(by: CGFloat(M_PI))
        }
    
        if (img.imageOrientation == UIImageOrientation.left
            || img.imageOrientation == UIImageOrientation.leftMirrored) {
    
            transform = transform.translatedBy(x: img.size.width, y: 0)
            transform = transform.rotated(by: CGFloat(M_PI_2))
        }
    
        if (img.imageOrientation == UIImageOrientation.right
            || img.imageOrientation == UIImageOrientation.rightMirrored) {
    
            transform = transform.translatedBy(x: 0, y: img.size.height);
            transform = transform.rotated(by: CGFloat(-M_PI_2));
        }
    
        if (img.imageOrientation == UIImageOrientation.upMirrored
            || img.imageOrientation == UIImageOrientation.downMirrored) {
    
            transform = transform.translatedBy(x: img.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        }
    
        if (img.imageOrientation == UIImageOrientation.leftMirrored
            || img.imageOrientation == UIImageOrientation.rightMirrored) {
    
            transform = transform.translatedBy(x: img.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(img.size.width), height: Int(img.size.height),
                                      bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                      space: img.cgImage!.colorSpace!,
                                      bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!
    
        ctx.concatenate(transform)
    
    
        if (img.imageOrientation == UIImageOrientation.left
            || img.imageOrientation == UIImageOrientation.leftMirrored
            || img.imageOrientation == UIImageOrientation.right
            || img.imageOrientation == UIImageOrientation.rightMirrored
            ) {
    
    
            ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))
    
        } else {
            ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
        }
    
    
        // And now we just create a new UIImage from the drawing context
        let cgimg:CGImage = ctx.makeImage()!
        let imgEnd:UIImage = UIImage(cgImage: cgimg)
    
        return imgEnd
    }
    
  • 2

    UIImage 有一个属性 imageOrientation ,它指示 UIImageView 和其他 UIImage 消费者旋转原始图像数据 . 这个标志很有可能被保存到上传的jpeg图像中的exif数据,但是用来查看它的程序并没有遵守该标志 .

    要在上传时旋转 UIImage 以正确显示,您可以使用如下类别:

    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
    
  • 4

    如果启用编辑,则编辑后的图像(与原始图像相对)将按预期方向定向:

    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
    }
    

    启用编辑允许用户在点击“使用照片”之前调整图像大小并移动图像

  • 3

    基于_107931的答案更新Swift 3.1,代码清理 .

    extension UIImage {
        func fixedOrientation() -> UIImage {
            if imageOrientation == .up { 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/2)
            case .right, .rightMirrored:
                transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
            default: break
            }
    
            switch imageOrientation {
            case .upMirrored, .downMirrored:
                transform = transform.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
            case .leftMirrored, .rightMirrored:
                transform = transform.translatedBy(x: size.height, y: 0).scaledBy(x: -1, y: 1)
            default: break
            }
    
            let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
                                           bitsPerComponent: cgImage!.bitsPerComponent, bytesPerRow: 0,
                                           space: cgImage!.colorSpace!, bitmapInfo: cgImage!.bitmapInfo.rawValue)!
            ctx.concatenate(transform)
    
            switch imageOrientation {
            case .left, .leftMirrored, .right, .rightMirrored:
                ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.height,height: size.width))
            default:
                ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width,height: size.height))
            }
            return UIImage(cgImage: ctx.makeImage()!)
        }
    }
    

    Picker委托方法示例:

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        guard let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
        let fixedImage = originalImage.fixedOrientation()
        // do your work
    }
    
  • 1

    如果我明白,你想要做的是忽视UIImage的方向?如果是这样,你可以这样做: -

    //image is your original image
    image = [UIImage imageWithCGImage:[image CGImage]
                                 scale:[image scale]
                           orientation: UIImageOrientationUp];
    

    或者在Swift中: -

    image = UIImage(CGImage: image.CGImage!, scale: image.scale, orientation:.Up)
    

    它解决了我的裁剪问题..希望,这就是你要找的......

  • 5

    这是我找到的修复方向问题

    UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    NSData *data = UIImagePNGRepresentation(self.initialImage);
    
    UIImage *tempImage = [UIImage imageWithData:data];
    UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
                                         scale:initialImage.scale
                                   orientation:self.initialImage.imageOrientation];
    initialImage = fixedOrientationImage;
    

    EDIT:

    UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    NSData *data = UIImagePNGRepresentation(self.initialImage);
    
    initialImage = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage
                                                         scale:initialImage.scale
                                                   orientation:self.initialImage.imageOrientation];
    
  • 12

    这是@ an0的答案的Swift版本:

    func normalizedImage() -> UIImage {
    
      if (self.imageOrientation == UIImageOrientation.Up) { 
          return self;
      }
    
      UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
      let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
      self.drawInRect(rect)
    
      let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext();
      return normalizedImage;
    }
    

    还有一个更通用的功能:

    func fixOrientation(img:UIImage) -> UIImage {
    
      if (img.imageOrientation == UIImageOrientation.Up) { 
          return img;
      }
    
      UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
      let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
      img.drawInRect(rect)
    
      let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext();
      return normalizedImage;
    
    }
    

    Swift 3版本:

    func fixOrientation(img: UIImage) -> UIImage {
        if (img.imageOrientation == .up) {
            return img
        }
    
        UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
        let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
        img.draw(in: rect)
    
        let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
    
        return normalizedImage
    }
    
  • 106

    我在设计拍摄照片的应用程序时使用了此页面,我发现以下方法将纠正方向并使用比以前的答案更少的内存和处理器:

    CGImageRef cgRef = image.CGImage;
    image = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationUp];
    

    这基本上只是用新方向重新拍摄实际图像数据 . 我正在使用@ an0的代码,但它在内存中创建了一个新图像,这可能会对您从相机获得的3264x2448图像造成负担 .

  • 0

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

    我已经更新了jake和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)!)
        }
    }
    

    在您的代码中使用此UIImage扩展:

    let fixOrientationImage=chosenImage.fixOrientation()

    把它放在像这样的图像选择器的委托方法中

    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)
        }
    
  • 10

    我想出了一个更简单的问题:

    - (UIImage *)normalizedImage {
        if (self.imageOrientation == UIImageOrientationUp) return self; 
    
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        [self drawInRect:(CGRect){0, 0, self.size}];
        UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return normalizedImage;
    }
    

    BTW:@ Anomie的代码不考虑 scale ,因此不适用于2x图像 .

  • 3

    这是swift的UIImage扩展:

    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.
            var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
                CGImageGetBitsPerComponent(self.CGImage), 0,
                CGImageGetColorSpace(self.CGImage),
                CGImageGetBitmapInfo(self.CGImage));
    
            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))!
        }
    }
    

    基于MetalHeart2003的早期工作..

  • 231

    这是基于@Anomie接受的答案的Swift 2中的UIImage扩展 . 它使用更清晰的开关盒 . 它还会考虑 CGBitmapContextCreateImage() 返回的可选值 .

    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
            }
        }
    }
    
  • 38

    Swift 4.1版 @an0 的解决方案:

    extension UIImage {
        func upOrientationImage() -> UIImage? {
            switch imageOrientation {
            case .up:
                return self
            default:
                UIGraphicsBeginImageContextWithOptions(size, false, scale)
                draw(in: CGRect(origin: .zero, size: size))
                let result = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return result
            }
        }
    }
    
  • 503

    基于@ jake1981的Swift 3版本是从@ 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

    我从相机拍摄的图像或保存在相机胶卷中拍摄的照片都经历过这个问题 . 从safari浏览器下载到照片库中的图像在上传时不会旋转 .

    我可以通过在上传之前将图像数据设置为JPEG来解决此问题 .

    let image = info[UIImagePickerControllerOriginalImage] as! UIImage        
    let data = UIImageJPEGRepresentation(image, 1.0)
    

    我们现在可以使用数据进行上传,上传后图片不会旋转 .

    希望这会奏效 .

相关问题