如何将图像方向应用于 CIImage?

How to apply image orientation to a CIImage?

我尝试使用 CIFilter 合成 2 张图像,但我无法正确处理图像方向。

在下面的示例中,我捕获了相同的场景,但 phone 有两个不同的方向(第一张图像的音量按钮在顶部,第二张图像的底部)。在下面的屏幕截图中,第一张图像显示在顶部,第二张图像显示在中间。我验证了 2 个图像方向不同(cf print 调用)。

SwiftUI 正确处理图像方向。如果我现在使用 CIFilter(第三张图片)合成 2 张图片,则不会考虑图片的方向,合成也不是我想要的(我想要并排放置 2 个杯子)。

这显然不是错误。但是如何在应用合成 CIFIlter 之前根据它们各自的方向旋转输入图像?这样做的标准方法是什么?

感谢您的帮助。

下面是这个简单例子对应的代码:

import SwiftUI

struct ContentView: View {

    @State var input1 = UIImage(named: "image1.jpg")
    @State var input2 = UIImage(named: "image2.jpg")
    @State var output : UIImage?

    var body: some View {
        VStack {

            Image(uiImage: input1!)
                .resizable()
                .scaledToFit()

            Image(uiImage: input2!)
                .resizable()
                .scaledToFit()

            if output != nil {
                Image(uiImage: output!)
                    .resizable()
                    .scaledToFit()
            }

        }
        .onAppear(){
            self.compose()
        }
    }

    func compose() {

        print("Orientation of input1: \(input1!.imageOrientation.rawValue)")
        print("Orientation of input2: \(input2!.imageOrientation.rawValue)")

        let ciContext = CIContext(options: nil)

        let ciInput1 = CIImage(image: input1!)
        let ciInput2 = CIImage(image: input2!)

        let filter = CIFilter(name: "CILinearDodgeBlendMode")!
        filter.setValue(ciInput1, forKey: "inputImage")
        filter.setValue(ciInput2, forKey: "inputBackgroundImage")

        let ciOutput = filter.value(forKey: kCIOutputImageKey) as! CIImage

        let cgOutput = ciContext.createCGImage(ciOutput, from: ciOutput.extent)!

        output = UIImage(cgImage: cgOutput)
    }
}

这是相应的屏幕截图:

您可以告诉 Core Image 在加载时考虑图像的方向:

let ciInput1 = CIImage(image: input1!, options: [.applyOrientationProperty: true])
let ciInput2 = CIImage(image: input2!, options: [.applyOrientationProperty: true])

编辑:

所以上面的方法似乎只在从 URL 或数据加载图像时才有效,而不是从 UIImage.

不过,您可以自己应用方向。这是一个方便的扩展:

extension UIImage.Orientation {
    var exifOrientation: Int32 {
        switch self {
            case .up: return 1
            case .down: return 3
            case .left: return 8
            case .right: return 6
            case .upMirrored: return 2
            case .downMirrored: return 4
            case .leftMirrored: return 5
            case .rightMirrored: return 7
        }
    }
}

然后你可以像这样变换图像:

let ciInput1 = CIImage(image: input1!).oriented(forExifOrientation: image1.imageOrientation.exifOrientation)
let ciInput2 = CIImage(image: input2!).oriented(forExifOrientation: image2.imageOrientation.exifOrientation)