How to save an image as PNG or HDR?

I am using 27 Inch Retina Mac to generate images saving them as files.

Using Scenekit to buld a scene then transfered to Metal texture I can save as .PNG.

The biggest I can get is 7.2K by 7.2K but no bigger.


How to save as HDR or 32 bit TIFF in bigger size?

I think you are going to have to use NSData and it'swrite(toFile:atomically:) method to save an image to the desired file format by yourself.


Check the HDR or TIFF image file format specification.

Actually, there is an even better way ! The Image I/O framework:


"The Image I/O framework provides opaque data types for reading image data from a source (

CGImageSourceRef
) and writing image data to a destination (
CGImageDestinationRef
). It supports a wide range of image formats, including the standard web formats, high dynamic range images, and raw camera data."


"The Image I/O framework understands most of the common image file formats, such as JPEG, JPEG2000, RAW, TIFF, BMP, and PNG."


https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/ImageIOGuide/imageio_intro/ikpg_intro.html#//apple_ref/doc/uid/TP40005462


https://developer.apple.com/reference/imageio

Here is what I am using:

macOS 10.12

in:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {


...

DispatchQueue.main.async {

SCNTransaction.begin()

SCNTransaction.disableActions = true

let snapshot = gView.snapshot()

let repr = self.TIFFRepresentation(image: snapshot)

do{

_ = try repr?.write(to: fileUrl as! URL, options: NSData.WritingOptions.atomicWrite)

}

catch let error as NSError {

print(error.localizedDescription)

}

SCNTransaction.commit()

}

...

func TIFFRepresentation(image: NSImage) -> Data? {

if let TIFFRepresentation = image.tiffRepresentation, let bitmap = NSBitmapImageRep(data: TIFFRepresentation) {

return bitmap.representation(using: .TIFF, properties: [:])

}


return nil

}


The resulting TIFF file is 8 bit per channel. Color Profile: sRGB IEC61966-2.1


It should be 32-bit per channel,

Color Profile: Wide Gamut RGB (Linear RGB Profile)




Also I can get bigger resolutions like 7.2Kx7.2K using Metal:

===

func setupMetal() {

if gView.renderingAPI == SCNRenderingAPI.metal {

let device = gView.device

commandQueue = device?.makeCommandQueue()

/

SCNRenderer

An SCNRenderer object renders a SceneKit scene into an arbitrary Metal workflow or OpenGL context. Use this class when you want to add content rendered by SceneKit to an app that already renders other content by using Metal or OpenGL or OpenGL ES directly. To provide content for a SceneKit renderer, assign a SCNScene object to its scene property.

*/

renderer = SCNRenderer(device: device, options: nil)


} else {

fatalError("Sorry, Metal only")

}

}

===

and then:

===

func doRender() -> NSImage{

/

let rect = CGRect(x: 0, y: 0, width: CGFloat(textureSizeX), height: CGFloat(textureSizeY))


let viewport = rect

let renderPassDescriptor = MTLRenderPassDescriptor()

let commandBuffer = commandQueue.makeCommandBuffer()


renderer.scene = scene

renderer.pointOfView = gView.pointOfView

renderer.render(atTime: 0, viewport: viewport, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)


commandBuffer.commit()

/

let size = CGSize(width: textureSizeX, height: textureSizeY)

let img = renderer.snapshot(atTime: 0, with: size, antialiasingMode: .none)

print(img)

return img

/


}


Basically utilizing Metal's renderer.snapshot of the scene. This is giving me benefit of 2x offscreen size.

The question is how to get HDR image possibly using Image I/O framework?

How to save an image as PNG or HDR?
 
 
Q