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


当前回答

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

我能够通过在上传之前将图像数据制作为JPEG来解决这个问题。

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

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

希望这能奏效。

其他回答

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

我能够通过在上传之前将图像数据制作为JPEG来解决这个问题。

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

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

希望这能奏效。

基于Sourabh Sharma的回答更新了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()!)
    }
}

选取器委托方法示例:

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

如果我没理解错的话,你想做的是忽略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)

它解决了我的裁剪问题。霍普,这就是你要找的…

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

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

这基本上只是用一个新的方向重新包装实际的图像数据。我使用@an0的代码,但它使一个新的图像在内存中,这可能是一个326x2448的图像,你可能会从相机。

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