Home > Net >  How to programmatically export any MTLTexture to KTX in Swift
How to programmatically export any MTLTexture to KTX in Swift

Time:09-22

Detail

We can export the raw texture data including other layers or slices in KTX format after we capture the frame by enter image description here

After that, we can import by using MTKTextureLoader.

let texture = try! await loader.newTexture(URL: Bundle.main.url(forResource: "texture", withExtension: "ktx")!)

Goal

But how to programmatically export the MTLTexture to KTX format in Swift?

CodePudding user response:

You can check ImageIO whether ImageIO supports the format you want to export to:

Call CGImageDestinationCopyTypeIdentifiers() from ImageIO module to get a list of all the UTI that the CGImageDestination supports.

For example, these are the types ImageIO supports on my machine:

(
    "public.jpeg",
    "public.png",
    "com.compuserve.gif",
    "public.tiff",
    "public.jpeg-2000",
    "com.apple.atx",
    "org.khronos.ktx",
    "org.khronos.ktx2",
    "org.khronos.astc",
    "com.microsoft.dds",
    "public.heic",
    "public.heics",
    "com.microsoft.ico",
    "com.microsoft.bmp",
    "com.apple.icns",
    "com.adobe.photoshop-image",
    "com.adobe.pdf",
    "com.truevision.tga-image",
    "com.ilm.openexr-image",
    "public.pbm",
    "public.pvr"
)

Then, use CGImage to output it:

let texture: MTLTexture = ... // input texture
let ciContext = CIContext(mtlDevice: texture.device)
let ciImage = CIImage(mtlTexture: texture, options: nil) // you might need to add `.oriented(.downMirrored)` here
let colorspace = CGColorSpace(name: CGColorSpace.sRGB)
let cgImage = ciContext.createCGImage(ciImage, from: .init(origin: .zero, size: .init(width: texture.width, height: texture.height)), format: .RGBA8, colorSpace: colorspace)!

let uniformType: UTType = ... // uniform type from CGImageDestinationCopyTypeIdentifiers
let outputURL: URL = ... // the url

try FileManager.default.createDirectory(at: outputURL.deletingLastPathComponent(), withIntermediateDirectories: true) // you might needs this to create intermediate directories

let destination = CGImageDestinationCreateWithURL(outputURL as CFURL, uniformType.identifier as CFString, 1, nil)!
CGImageDestinationAddImage(destination, cgImage, nil)
let imageOutputSuccessfully = CGImageDestinationFinalize(destination)
  • Related