如何将图像方向应用于 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)
我尝试使用 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)