我正在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 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
}

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

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

    UIGraphicsBeginImageContext(image.size)

    image.draw(at: .zero)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage ?? image
}

Swift 4.x/5.0版本的@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
        }
    }
}

我通过在下面写几行代码来实现这一点

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

这是一个不改变原始图像颜色空间的解决方案。如果你想规范化一个灰度图像的方向,你不会幸运地使用所有基于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()!)
    }
}