2

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

UIImage(CGImage: asset.fullScreenImage!.CGImage!, scale: scale, orientation: UIImageOrientation.Up)用来确保我的图像在缩略图中保持不变。asset.fullResolutionImage!这样做是行不通的。

现在是奇怪的部分。当我用 iPhone 相机拍照时,然后前往我的裁剪视图控制器,图像旋转了 90 度!我不知道为什么。

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

这是什么原因?如何解决它?

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

4

3 回答 3

1

您可以尝试使用此类别:

UIImage+FixOrientation.h

UIImage+FixOrientation.m

它是在 Objective-C 中构建的,然后您可以使用桥接头ObjCSwift结合使用,或者您可以看一下以了解如何解决该问题。

使用示例:

UIImage *image = <image from camera image>
image = [image fixOrientation];
于 2015-08-29T08:07:14.603 回答
0

这个答案是对gontovnik 的回答的补充。

我采用了他的 Objective-C 解决方案并用 Swift 编写。将此功能放在需要的地方。只需传入有问题的 UIImage 即可。

也就是说,您可能只是将其设为 UIImage 类函数。实际上只是打电话会很好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!
}
于 2015-08-29T08:35:54.210 回答
0

斯威夫特 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
  }
于 2017-07-14T07:30:00.233 回答