【问题标题】:Taking pictures with camera rotates asset.fullScreenImage 90 degrees?用相机拍照将asset.fullScreenImage旋转90度?
【发布时间】:2015-08-29 07:52:15
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: ios iphone uiimagepickercontroller ios-camera


    【解决方案1】:

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

    UIImage+FixOrientation.h

    UIImage+FixOrientation.m

    它是用Objective-C构建的,那么你可以使用bridging header来结合ObjCSwift,或者你可以看看了解如何解决这个问题。

    使用示例:

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

    【讨论】:

    • 嗯,解决了它,但为什么会发生这种情况?这是iOS 8的错误吗?此解决方案是否适用于 iOS 4-7 等?另外,也许这只是我的眼睛,但看起来我最后得到的图像,虽然方向正确,但质量略低。
    • 不,这不是一个真正的问题。当你拍照时,它需要设备方向(这就是我的想法,不是 100% 确定它是正确的),所以这是修复我从 iOS 6 开始使用的那个的解决方案。嗯,质量不应该像他们那样低不缩放,只旋转。
    • 是的,我拍了更多照片,我很确定我的眼睛在欺骗我:P。好的。万分感谢!那么从 iOS 6 开始就一直在发生这种情况?
    • 可能在 iOS 6 之前就已经发生了。正如我在 stackoverflow 中看到的那样,人们从 2011 年开始就面临着这个问题。我认为这是非常罕见的问题。这甚至都不是问题,这只是相机的工作原理。 :)
    • 顺便说一句,我发布了另一个答案,基本上是你的代码,但在 Swift 中。随意看看。
    【解决方案2】:

    这个答案是对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!
    }
    

    【讨论】:

    • 我唯一推荐的就是将它设为 UIImage extension 而不是函数。
    • 是的,我同意。写在上面的代码 sn-p :)
    【解决方案3】:

    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
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多