CIContext JPEG/PNG 输出函数生成空白图像

CIContext JPEG/PNG output functions producing blank images

我正在尝试将 CIImage 输出到磁盘,并且正在寻找最有效的方法。我找到了 ,这表明使用 CIContext 的 writeJPEGRepresentation/writePNGRepresentation 方法。但是,每当我尝试使用这些方法时,它们都会生成空白图像。

对于 JPEG,它会生成纯黑色图像。 PNG 生成纯透明图像。 HEIF 方法也产生了纯黑色图像。如果我使用生成 DatajpegRepresentationpngRepresentation 方法而不是直接写入磁盘,结果相同。

如果我改为使用 createCGImage 渲染这些对象,然后从 CGImage 中写出数据,它们看起来很好。

知道为什么会这样吗?

这是一个说明问题的简单示例:

let ciImage = CIImage(contentsOf: photoURL, options: [CIImageOption.applyOrientationProperty: true])!

let context = CIContext()
try! context.writeJPEGRepresentation(of: ciImage, to: FileManager.default.temporaryDirectory.appendingPathComponent("testFromCIImage.jpeg"), colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!, options: [:])

let cgImage: CGImage = context.createCGImage(ciImage, from: ciImage.extent)!
let uiImage = UIImage(cgImage: cgImage)
try! uiImage.jpegData(compressionQuality: 1.0)!.write(to: FileManager.default.temporaryDirectory.appendingPathComponent("testFromUIImage.jpeg"))

testFromCIImage.jpeg 显示为空白图像,与原始输入图像大小相同。 testFromUIImage.jpeg 看起来与输入图像相同。

我创建了一个 sample project 来说明这个问题,以及一些示例图片。

更新

我发现只有一种情况可以正确输出图像 - 当源图像是 PNG,并且 writeJPEGRepresentationcolorSpace 参数匹配源的颜色 space图片。我没有成功使用任何 JPEG,即使颜色 space 匹配。

正如您所说,这似乎是模拟器独有的问题。然而,我做了更多的挖掘并发现了以下内容:

在检查 Core Image 正在做什么时(通过设置 CI_PRINT_TREE 环境变量)我发现这棵树看起来很正常(尽管生成的图像是黑色的)。 但是,对于工作配置 什么 都没有打印!在我看来,Core Image 实际上并没有进行任何渲染,但可能 Image I/O 直接用于编写 JPG。

这让我尝试通过在上下文创建时传递 CIContextOption.useSoftwareRenderer 来强制 Core Image 使用软件渲染器(而不是其默认的 Metal 渲染器)。然而,这完全被忽略了。结果上下文仍然是 Metal 上下文...

是的,现在看来唯一可行的解​​决方法是通过 CGImage。如果您能向 Apple 提交错误,那就太好了。