Ios 当我将MTLTexture保存到CGImage时,像素颜色会改变吗?

Ios 当我将MTLTexture保存到CGImage时,像素颜色会改变吗?,ios,ios11,metal,cgimage,color-space,Ios,Ios11,Metal,Cgimage,Color Space,我需要保存金属纹理并将其加载到文件中。下面的示例代码如下。我注意到RGB值在保存和重新加载时发生了变化 metal texture pixel: RGBA: 42,79,12,95 after save and reload: 66,88,37,95 它变得越来越亮,越来越灰。下一次保存时,它开始变暗。我在iPad Pro上,所以想知道这是否是一个色彩空间问题。有没有关于为什么会发生这种情况以及如何解决的建议 在下面保存cgImage的行中,我可以检查原始像素数据,看到RGBA是6

我需要保存金属纹理并将其加载到文件中。下面的示例代码如下。我注意到RGB值在保存和重新加载时发生了变化

metal texture pixel: RGBA: 42,79,12,95  
after save and reload:     66,88,37,95
它变得越来越亮,越来越灰。下一次保存时,它开始变暗。我在iPad Pro上,所以想知道这是否是一个色彩空间问题。有没有关于为什么会发生这种情况以及如何解决的建议

在下面保存
cgImage
的行中,我可以检查原始像素数据,看到RGBA是66,88,37

// saving...
let ciCtx = CIContext()
let ciImage = CIImage(mtlTexture: metalTexture, options: [:])
// [ … transfrom to flip y-coordinate …]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let cgImage = ciCtx.createCGImage(ciImage, from: fullRect, format: kCIFormatRGBA8, colorSpace: colorSpace)!
let imageDest = CGImageDestinationCreateWithData(mData, kUTTypePNG, 1, nil)!
CGImageDestinationAddImage(imageDest, cgImage, nil)
CGImageDestinationFinalize(imageDest)

// loading...
let src = CGImageSourceCreateWithData(imgData, nil)
let img = CGImageSourceCreateImageAtIndex(src, 0, nil)
let loader = MTKTextureLoader(device: self.metalDevice)
let texture = try! loader.newTexture(cgImage: img, options: [:])

我遇到了一个非常类似的问题。我认为,如果您将一些选项传递给CIImage(),而不是不进行颜色空间管理,即“options:[:]”,您将摆脱颜色偏移问题

let kciOptions = [kCIImageColorSpace: CGColorSpaceCreateDeviceRGB(),
                      kCIContextOutputPremultiplied: true,
                      kCIContextUseSoftwareRenderer: false] as [String : Any]
let ciImage = CIImage(mtlTexture: metalTexture, options: kciOptions)

当我遇到问题时,上述方法对我有效。

一般来说,PNG数据是以sRGB编码的方式存储的,但您告诉Core Image将纹理数据视为在设备的颜色空间中处理,可能是显示P3(您可以通过打印
颜色空间
来确定)。无论如何,设备颜色空间很少是您想要的。为CI提供sRGB颜色空间(
CGColorSpace(名称:CGColorSpace.sRGB)
)可能是有意义的。当纹理加载器加载图像时,它应该推断图像数据是sRGB,您应该会看到更好的结果。当我打印
颜色空间
对象时,它给出:
(kCGColorSpaceDeviceRGB)
,它似乎不是显示P3。我刚刚尝试使用.sRGB和.displayP3来创建颜色空间,这两种颜色都会在保存和重新加载时发生变化。必须有办法保存像素图并返回相同的RGB值。谢谢@Plutovman!你知道目标C代码中的等价物吗?NSDictionary对象将不接受CGColorSpaceRef作为值。不幸的是,我不接受,因为我的Objective-C知识非常少。我相信你很快就会找到路的。Best.for objective c用法:@{kCIImageColorSpace:(uuu bridge_transfer id)CGColorSpaceCreateDeviceRGB()}