2

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

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

如果我改为使用 渲染这些对象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看起来与输入图像相同。

我创建了一个示例项目来说明该问题,以及一些示例图像。

更新

我只发现图像输出正确的一种情况 - 当源图像是 PNG,并且colorSpace参数writeJPEGRepresentation与源图像的颜色空间匹配时。即使色彩空间匹配,我也没有成功使用任何 JPEG。

4

1 回答 1

2

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

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

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

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

于 2020-05-04T18:48:56.620 回答