Convert PNG image with transparency to KTX format

#1

Greetings.

I am new to working with image formats, so i was happy to successfully load and display a KTX image in my OpenGL application.
Howerver, i am not able to create KTX images that have transparency, here’s what i do:

  1. I create a and save PNG images that have transparency (with gimp).
    > identify image.png
    > image.png PNG 256x256 256x256+0+0 8-bit sRGB 41.9KB 0.000u 0:00.000

  2. I use ImageMagick’s ‘convert’ tool to create a PAM file:
    > convert image.png PNG8:image.pam
    > identify image.pam
    > image.pam PNG 256x256 256x256+0+0 8-bit sRGB 4.96KB 0.000u 0:00.000

  3. I call toktx to convert to KTX:
    > toktx image image.pam
    > toktx: “image.pam” is not a valid .pam, .pgm or .ppm file

Certainly i’m doing something wrong, so i searched the net for help, but there are so many formats and tools
that i got lost. Can you help me, please?

[Edit]
> toktx --version
> toktx version 1.1

Regards,
Alfred

#2

There is not enough information here to tell if the PNG has an alpha channel or not. You’ll need to use identify -verbose.

Are you sure you exported the alpha channel? I haven’t used gimp but the image tools I have used require you to make an explicit selection to export an alpha channel to a PNG.

This command is actually telling convert to output the image in PNG8 format even though the output file has the extension .pam. convert image.png image.pam should be sufficient. PNG8 is “8-bit indexed with optional binary transparency” and judging by the file size, which is considerably smaller than the input, 8-bit indexed is what you got. You need a full alpha channel for use with OpenGL* and toktx.

  • There is an OES_compressed_palletted texture extension for OpenGL ES 1.x but toktx does not support creating KTX files with this format as they are almost never used any more.
#3

[QUOTE=markc;42185]There is not enough information here to tell if the PNG has an alpha channel or not. You’ll need to use identify -verbose.

Are you sure you exported the alpha channel? I haven’t used gimp but the image tools I have used require you to make an explicit selection to export an alpha channel to a PNG…[/QUOTE]

Yes, i checked that i exported the alpha channel, here’s the output of identify:

> identify -verbose image.png
Image: image.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 256x256+0+0
Units: Undefined
Type: Bilevel
Endianess: Undefined
Colorspace: Gray
Depth: 8-bit
Channel depth:
gray: 1-bit
alpha: 8-bit
Channel statistics:
Pixels: 65536
Gray:
min: 0 (0)
max: 255 (1)
mean: 171.274 (0.671661)
standard deviation: 119.75 (0.469609)
kurtosis: -1.46552
skewness: -0.731083
Alpha:
min: 0 (0)
max: 154 (0.603922)
mean: 46.7438 (0.183309)
standard deviation: 47.4481 (0.186071)
kurtosis: -1.10392
skewness: -0.561214
Alpha: graya(0,0) #00000000
Colors: 154
Histogram: [i omit pasting histogram]
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: graya(255,1)
Border color: graya(223,1)
Matte color: graya(189,1)
Transparent color: graya(0,0)
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 256x256+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2017-04-16T12:53:01+01:00
date:modify: 2017-04-14T00:30:50+01:00
png:IHDR.bit-depth-orig: 8
png:IHDR.bit_depth: 8
png:IHDR.color-type-orig: 6
png:IHDR.color_type: 6 (RGBA)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 256, 256
png:sRGB: intent=0 (Perceptual Intent)
signature: 3ca1b94743929485e631d005846b1540caff49cc0ada5bade4b5ce64aaa6dc31
Artifacts:
filename: image.png
verbose: true
Tainted: False
Filesize: 41.9KB
Number pixels: 65.5K

Thanks for explaining that. The reason i was calling convert this way is because in my first attempts on loading and displaying the converted KTX image i got black color instead of transparency and i was desperate. I tried again the way you described. Now ‘identify image.pam’ gives me the same output for alpha as for image.png, the file size is considerably bigger:

identify -verbose image.pam
Image: image.pam
Format: PAM (Common 2-dimensional bitmap format)
Mime type: image/x-portable-pixmap
Class: DirectClass
Geometry: 256x256+0+0
Units: Undefined
Type: Bilevel
Endianess: Undefined
Colorspace: Gray
Depth: 8-bit
Channel depth:
gray: 1-bit
alpha: 8-bit
Channel statistics:
Pixels: 65536
Gray:
min: 0 (0)
max: 255 (1)
mean: 171.274 (0.671661)
standard deviation: 119.75 (0.469609)
kurtosis: -1.46552
skewness: -0.731083
Alpha:
min: 0 (0)
max: 154 (0.603922)
mean: 46.7438 (0.183309)
standard deviation: 47.4481 (0.186071)
kurtosis: -1.10392
skewness: -0.561214
Alpha: graya(0,0) #00000000
Colors: 154
Histogram: omiited
Rendering intent: Undefined
Gamma: 0.454545
Background color: graya(255,1)
Border color: graya(223,1)
Matte color: graya(189,1)
Transparent color: graya(0,0)
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 256x256+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: Undefined
Properties:
date:create: 2017-04-16T13:56:07+01:00
date:modify: 2017-04-16T13:56:07+01:00
signature: 3ca1b94743929485e631d005846b1540caff49cc0ada5bade4b5ce64aaa6dc31
Artifacts:
filename: image.pam
verbose: true
Tainted: False
Filesize: 131KB
Number pixels: 65.5K

But even though now toktx creates a valid KTX file, i still get no transparency. Besides that the image is displayed correctly.
Do i fail in setting up the format correctly? Here’s a code snippet:


        glGetIntegerv( GL_UNPACK_ALIGNMENT, &unpack_alignment );
	if( KTX_UNPACK_ALIGNMENT != unpack_alignment ) {
		glPixelStorei( GL_UNPACK_ALIGNMENT, KTX_UNPACK_ALIGNMENT );
	}
        glTexImage2D( GL_TEXTURE_2D, 0, ktx_header.internal_format,
			ktx_header.pixel_width, ktx_header.pixel_height,
			0, ktx_header.format, GL_UNSIGNED_BYTE, pixel_data );

I wrote my own KTX loader and am using the values as i get them from the KTX header and also set the unpack alignment as stated in the format description.
Since calling glGetError never showed something, i thought i was doing that part correctly.
Sorry for my ignorance, the topic is quite overwhelming. Maybe you have a suggestion what i could try or what i should investigate/read to solve this.

Regards and many thanks,
Alfred

#4

After some time of testing different texture tools i finally found one that can convert PNG to KTX format exactly the way i wanted and expected: PVRTexTool.
I am very pleased to see that contrary to me assuming i messed up my code or image creation/saving, i did it right.
Still, i would like to know what the correct way of doing it with ImageMagick would be.

Regards and thanks,
Alfred

#5

PVRTexTool is a utility for compressing textures, which is an important technique that ensures the lowest possible texture memory overhead at application run-time. The PVRTexTool package includes a library, command-line and GUI tools, and a set of plug-ins. Plug-ins are available for Autodesk 3ds Max, Autodesk Maya, and Adobe Photoshop.

Each component is capable of converting to a variety of popular compressed texture formats such as PVRTC and ETC, as well as all of the core texture formats for a variety of different APIs. They also include a number of advanced features to pre-process the image data, for example, border generation, colour bleeding and normal map generation.

Textures can be saved to DDS, KTX, or PVR (Imagination’s PowerVR Texture Container format which benefits from full public specification, support for custom metadata, as well as complete and optimized resource loading code in the PVRTools).