swift - 如何将图像方向应用于 CIImage?
问题描述
我尝试使用 CIFilter 合成 2 个图像,但我无法正确处理图像方向。
在下面的示例中,我捕获了相同的场景,但手机有 2 个不同的方向(第一张图像顶部的音量按钮,第二张图像底部的音量按钮)。在以下屏幕截图中,第一张图片显示在顶部,第二张图片显示在中间。我验证了 2 个图像方向不同(cfprint
调用)。
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)
推荐阅读
- spreadsheetgear - 在 SpreadsheetGear 中为受保护的工作表上的大纲/组启用展开/折叠按钮
- macos - 如何在 macOS 上的 zsh 中为“cd ..”添加补全?
- c# - 更改调试器消息的语言
- xpath - 无法使用 xpath 选择元素
- python-3.x - 在 Python3 中相互创建掩码或边界
- reactjs - 如何在 redux 中使用 Auth0 JWT 访问 API?
- java - 无法下载内容类型为 text/html 的文件
- google-apps-script - 如何在执行后删除谷歌脚本ClockTrigger
- sql - 错误 42803。列 XXXX 必须显示子句 GROUP BY 或在聚合函数中使用
- node.js - 节点 cron 作业仅在 GCP App Engine 上第一次执行