我正在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中显示的图像是正确的(直接在拍照后),但在服务器上查看则不然。


当前回答

我把这个换成了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;
    }

其他回答

下面是Swift-4.2自动修正图像方向的代码 返回界面图像

func AutofixImageOrientation(_ image: UIImage)->UIImage {

    UIGraphicsBeginImageContext(image.size)

    image.draw(at: .zero)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage ?? image
}

如果你启用了编辑,那么编辑后的图像(与原始图像相反)将按照预期的方向:

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
}

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

这是一个不改变原始图像颜色空间的解决方案。如果你想规范化一个灰度图像的方向,你不会幸运地使用所有基于UIGraphicsBeginImageContextWithOptions的解决方案,因为它在RGB颜色空间中创建了一个上下文。相反,你必须创建一个具有与原始图像相同属性的上下文并绘制:

extension UIImage {
    static let rotatedOrentations: [UIImage.Orientation] = [.left, .leftMirrored, .right, .rightMirrored]

    func normalizedImage() -> UIImage {
        if imageOrientation == .up {
            return self
        }

        let image = self.cgImage!
        let swapOrientation = UIImage.rotatedOrentations.contains(imageOrientation)
        let width = swapOrientation ? image.height : image.width
        let height = swapOrientation ? image.width : image.height
        let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.bitmapInfo.rawValue)!
        let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height));
        context.concatenate(flipVertical)
        UIGraphicsPushContext(context)
        self.draw(at: .zero)
        UIGraphicsPopContext()

        return UIImage(cgImage: context.makeImage()!)
    }
}
@an0, thanks for the answer!
The only thing is autoreleasepool: 

func fixOrientation(img: UIImage) -> UIImage? {

    let result: UIImage?
    if img.imageOrientation == .up {
        result = img
    } else {

        result = autoreleasepool { () -> UIImage? in
            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
        }
    }

    return result
}

Swift 3版本基于@jake1981,他从@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()!)

    }
}