gpt4 book ai didi

swift - CoreImage : CIImage write JPG is shifting colors [macOS]

转载 作者:行者123 更新时间:2023-12-03 20:58:56 25 4
gpt4 key购买 nike

使用 CoreImage 过滤照片,我发现保存为 JPG 文件会导致图像具有微妙但可见的蓝色色调。在这个使用黑白图像的示例中,直方图显示了颜色在保存的文件中是如何变化的。

---输入Input Histogram

输出 [ Output Histogram ] 直方图显示颜色层偏移

-- 使用 MacOS“预览”应用程序演示的问题

我可以仅使用预览应用程序显示类似的结果。

  • 此处测试图片:/image/Y3f03.jpg
  • 使用预览打开 JPG 图像。
  • 以除默认值(85%?)以外的任何“质量”导出为 JPEG
  • 打开导出的文件并查看直方图,可以看到与我在应用程序中体验到的相同的颜色偏移。

  • enter image description here

    -- 自定义 MacOS 应用程序中显示的问题

    这里的代码尽可能简单,从照片创建一个 CIImage 并立即保存它而不执行任何过滤器。在此示例中,我选择 0.61 进行压缩,因为它产生的文件大小与原始文件大小相似。如果使用更高的压缩比,失真似乎更广泛,但我找不到任何可以消除它的值。
    if let img = CIImage(contentsOf: url) {
    let dest = procFolder.url(named: "InOut.jpg")
    img.jpgWrite(url: dest)
    }

    extension CIImage {
    func jpgWrite(url: URL) {

    let prop: [NSBitmapImageRep.PropertyKey: Any] = [
    .compressionFactor: 0.61
    ]

    let bitmap = NSBitmapImageRep(ciImage: self)
    let data = bitmap.representation(using: NSBitmapImageRep.FileType.jpeg, properties: prop)

    do {
    try data?.write(to: url, options: .atomic)
    } catch {
    log.error(error)
    }
    }
    }

    更新 1:使用@Frank Schlegel 的答案保存 JPG 文件

    JPG 现在带有颜色同步配置文件,我可以(不科学地)跟踪纵向图像的性能提升约 10%(横向图像的性能提升更少),这是很好的改进。但是,不幸的是,生成的文件仍然以与上面直方图相同的方式倾斜颜色。
    extension CIImage {
    static let writeContext = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!, options: [
    // using an extended working color space allows you to retain wide gamut information, e.g., if the input is in DisplayP3
    .workingColorSpace: CGColorSpace(name: CGColorSpace.extendedSRGB)!,
    .workingFormat: CIFormat.RGBAh // 16 bit color depth, needed in extended space
    ])

    func jpgWrite(url: URL) {
    // write the output in the same color space as the input; fallback to sRGB if it can't be determined
    let outputColorSpace = colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)!
    do {
    try CIImage.writeContext.writeJPEGRepresentation(of: self, to: url, colorSpace: outputColorSpace, options: [:])
    } catch {
    }
    }
    }

    问题:

    如何将黑白 JPG 打开为 CIImage,并重新保存 JPG 文件以避免任何颜色偏移?

    最佳答案

    这看起来像是一个色彩同步问题(正如 Leo 指出的那样)——更具体地说,是输入、处理和输出之间色彩空间的不匹配/误解。

    当您调用 NSBitmapImageRep(ciImage:) 时,实际上发生了很多事情。系统实际需要渲染CIImage您提供的是获取结果的位图数据。它通过创建 CIContext 来实现。使用默认(特定于设备)设置,使用它来处理您的图像(应用所有过滤器和转换),然后为您提供结果的原始位图数据。在此过程中,使用此 API 时会发生您无法控制的多种色彩空间转换(并且似乎不会导致您想要的结果)。我不喜欢这些用于渲染的“方便”API CIImage出于这个原因,我看到很多关于 SO 的问题与他们相关。

    我建议您改用 CIContext呈现您的CIImage成 JPEG 文件。这使您可以直接控制色彩空间等:

    let input = CIImage(contentsOf: url)

    // ideally you create this context once and re-use it because it's an expensive object
    let context = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!, options: [
    // using an extended working color space allows you to retain wide gamut information, e.g., if the input is in DisplayP3
    .workingColorSpace: CGColorSpace(name: CGColorSpace.extendedSRGB)!,
    .workingFormat: CIFormat.RGBAh // 16 bit color depth, needed in extended space
    ])

    // write the output in the same color space as the input; fallback to sRGB if it can't be determined
    let outputColorSpace = input.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)!

    context.writeJPEGRepresentation(of: input, to: dest, colorSpace: outputColorSpace, options: [kCGImageDestinationLossyCompressionQuality: 0.61])

    如果您在使用此 API 时仍然发现差异,请告诉我。

    关于swift - CoreImage : CIImage write JPG is shifting colors [macOS],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59330149/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com