Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pixel colors change as I save MTLTexture to CGImage?

I need to save and load metal textures to a file. Example code below is below. I'm noticing the RGB values are changing as it gets saved and reloaded again.

metal texture pixel: RGBA: 42,79,12,95  
after save and reload:     66,88,37,95

That got brighter and grayer. Next save it starts getting darker. I'm on an iPad Pro so wondering if this is a colorspace issue. Any pointers on why this might be happening and how to fix it?

In the line below that is saving the cgImage, I can inspect the raw pixel data and see that the RGBA is 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: [:])
like image 884
Rob N Avatar asked Jan 02 '23 13:01

Rob N


1 Answers

I came across a very similar issue. I think if you pass some options to CIImage() rather than doing no colorspace management , i.e. "options: [:]" you'll get rid of the color offset issue.

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

The above worked for me when I was having this issue.

like image 90
Plutovman Avatar answered Jan 05 '23 15:01

Plutovman