我正在尝试将CIImage输出到磁盘,并正在寻找最有效的方法。我找到了this question,这建议使用CIContext的writeJPEGRepresentation
/ writePNGRepresentation
方法。但是,每当我尝试使用这些方法时,它们都会产生空白图像。
对于JPEG,它会产生纯黑色图像。 PNG产生纯透明图像。 HEIF方法还产生纯黑色图像。如果我使用生成jpegRepresentation
的pngRepresentation
或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
看起来与输入图像相同。
我创建了一个sample project来说明问题,并提供了一些示例图像。
更新
[我发现只有一种情况可以正确输出图像-当源图像是PNG,并且colorSpace
的writeJPEGRepresentation
参数与源图像的色彩空间匹配时。即使色彩空间匹配,我也没有使用任何JPEG成功。
正如您所说,这似乎是模拟器独有的问题。但是,我进行了一些进一步的挖掘,发现了以下内容:
[当检查Core Image在做什么时(通过设置CI_PRINT_TREE
环境变量),我发现树看起来很正常(尽管生成的图像是黑色的)。 但是,对于所有有效的配置,[[什么都没有已被打印!在我看来,Core Image实际上并未进行任何渲染,但也许Image I / O直接用于编写JPG。
CIContextOption.useSoftwareRenderer
来强制Core Image使用软件渲染器(而不是其默认的Metal渲染器)。但是,这完全被忽略。结果上下文仍然是金属上下文...是的,似乎唯一可行的解决方法是立即通过CGImage
。如果您要向Apple提交错误,那就太好了。