拍照相机旋转asset.fullScreenImage90度?

Taking pictures with camera rotates asset.fullScreenImage 90 degrees?

我让用户从他们的相机胶卷中选择一张照片进行剪裁。我将所有这些图片显示为缩略图供用户按。

我使用 UIImage(CGImage: asset.fullScreenImage!.CGImage!, scale: scale, orientation: UIImageOrientation.Up) 来确保我的图像在缩略图中的朝向保持不变。使用 asset.fullResolutionImage! 这不起作用。

奇怪的部分来了。当我用 iPhone 相机拍照,然后转到我的裁剪 ViewController 时,图像旋转了 90 度!我不知道为什么。

如果我离开我的应用程序,用相机正常拍照,将它保存到我的相机胶卷,然后像我选择其他照片一样从缩略图列表中选择它,它工作得很好。

这是什么原因?如何修复它?

编辑:下面发布了两个解决方案。一个在 Objective-C 中,另一个是将其翻译成 Swift.

你可以尝试使用这个分类:

UIImage+FixOrientation.h

UIImage+FixOrientation.m

它内置于Objective-C,那么你可以使用bridging header结合Swift使用ObjC ,或者您可以看一下以了解如何解决该问题。

用法示例:

UIImage *image = <image from camera image>
image = [image fixOrientation];

这个答案是为了补充 gontovnik 的答案。

我把他的Objective-C解法拿来写在Swift里了。把这个功能放在任何需要的地方。只需传入有问题的 UIImage。

也就是说,您可以将其设为 UIImage class 函数。只调用 UIImage.fixOrientation(image: imageInQuestion).

实际上会很好
func fixOrientation(image: UIImage) -> UIImage {
    // No-op if the orientation is already correct
    if (image.imageOrientation == UIImageOrientation.Up) { return image; }

    println(image.imageOrientation)

    // 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 (image.imageOrientation) {
        case .Down, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
            break
        case .Left, .LeftMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
            break        
        case .Right, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, image.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
            break            
        case .Up, .UpMirrored:
                break
    }

    switch (image.imageOrientation) {
        case .UpMirrored, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
            break       
        case .LeftMirrored, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
            break
        case .Up, .Down, .Left, .Right:
            break
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.

    var ctx = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage))

    CGContextConcatCTM(ctx, transform);

    switch (image.imageOrientation) {
        case .Left, .LeftMirrored, .Right, .RightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.height, image.size.width), image.CGImage)
            break

        default:
            CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage)
            break
    }

    // And now we just create a new UIImage from the drawing context
        var cgimg = CGBitmapContextCreateImage(ctx)
        var img = UIImage(CGImage: cgimg)

        return img!
}

Swift 3 版本

func fixOrientation(image: UIImage) -> UIImage {
    // No-op if the orientation is already correct
    if (image.imageOrientation == UIImageOrientation.up) { return image; }

    print(image.imageOrientation)

    // 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.identity

    switch (image.imageOrientation) {
    case .down, .downMirrored:
      transform = transform.translatedBy(x: image.size.width, y: image.size.height)
      transform = transform.rotated(by: CGFloat(M_PI))
      break
    case .left, .leftMirrored:
      transform = transform.translatedBy(x: image.size.width, y: 0)
      transform = transform.rotated(by: CGFloat(M_PI_2))
      break
    case .right, .rightMirrored:
      transform = transform.translatedBy(x: 0, y: image.size.height)
      transform = transform.rotated(by: CGFloat(-M_PI_2))
      break
    case .up, .upMirrored:
      break
    }

    switch (image.imageOrientation) {
    case .upMirrored, .downMirrored:
      transform = transform.translatedBy(x: image.size.width, y: 0)
      transform = transform.scaledBy(x: -1, y: 1)
      break
    case .leftMirrored, .rightMirrored:
      transform = transform.translatedBy(x: image.size.height, y: 0)
      transform = transform.scaledBy(x: -1, y: 1)
      break
    case .up, .down, .left, .right:
      break
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.

    let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image.cgImage!.bitsPerComponent, bytesPerRow: 0, space: image.cgImage!.colorSpace!, bitmapInfo: image.cgImage!.bitmapInfo.rawValue)

    ctx!.concatenate(transform);

    switch (image.imageOrientation) {
    case .left, .leftMirrored, .right, .rightMirrored:
      // Grr...
      ctx?.draw(image.cgImage!, in: CGRect(origin: .zero, size: CGSize(width: image.size.height, height: image.size.width)))

      break

    default:
      ctx?.draw(image.cgImage!, in: CGRect(origin: .zero, size: CGSize(width: image.size.width, height: image.size.height)))
      break
    }

    // And now we just create a new UIImage from the drawing context
    let cgimg = ctx!.makeImage()
    let img = UIImage(cgImage: cgimg!)

    return img
  }