Ключ оказался в отмене гамма-коррекции, встроенной в UIColor
let colorSRGB = UIColor(red: 0.92, green: 0.79, blue: 0.18, alpha: 1.0)
let rgbaSRGB = colorSRGB.getRGBAComponents()!
let gammapower : CGFloat = 2.2
let r = pow(rgbaSRGB.red, gammapower)
let g = pow(rgbaSRGB.green, gammapower)
let b = pow(rgbaSRGB.blue, gammapower)
let a = pow(rgbaSRGB.alpha, gammapower)
let colorNoGamma: UIColor = UIColor(red: CGFloat(r), green: CGFloat(g), blue: CGFloat(b), alpha: CGFloat(a))
Как только я передам colorNoGamma
для применения в MKTView с MTLPixelFormat.rgba16Float
, результаты будут соответствовать UIView с отображением colorSRGB
. Это имеет смысл, как только вы обдумаете это ... Спасибо @MoDJ за то, что вы ввели меня на правильный путь.
Обратите внимание, что на стороне MTKView я могу сохранить настройки текстуры в соответствии с первоначальным определением, а именно:
let texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: MTLPixelFormat.rgba8Unorm, width: Int(width), height: Int(height), mipmapped: isMipmaped)
target = texDescriptor.textureType
И, если я хочу преобразовать currentDrawable в текстуру, которая будет отображаться в UIImageView, то я хочу убедиться, что я не применяю ЛЮБЫЕ настройки цветового пространства. То есть:
let strokeCIImage = CIImage(mtlTexture: metalTextureComposite, options: [:])!.oriented(CGImagePropertyOrientation.downMirrored)
let imageCropCG = cicontext.createCGImage(strokeCIImage, from: box, format: kCIFormatABGR8, colorSpace: colorSpace) // kCIFormatRGBA8 gives same result. Not sure what's proper
let layerStroke = CALayer()
layerStroke.frame = bbox
layerStroke.contents = imageCropCG
Обратите внимание на аргумент options: [:]
означает, что я не передаю настройки цветового пространства / предварительного умножения / рендеринга, как я делал в оригинальном посте, где я определил kciOptions