That’s interesting. I didn’t know that ImageMagick would encode the image to a C/C++ header file.
That option doesn’t seem to give you what you want, but you can use the PAM format instead which is probably what you’re looking for. PAM is a simple PNM format which supports an alpha channel, and like the other PNM formats is trivial to read.
More detail…
Taking an RGBA PNG (RGB with an alpha channel) and converting it to a .h
file using ImageMagick:
> convert tux.png tux.h
results in an .h
file that starts like this:
/*
tux.h (PNM).
*/
static const unsigned char
MagickImage[] =
{
0x50, 0x36, 0x0A, 0x32, 0x38, 0x37, 0x20, 0x32, 0x30, 0x30, 0x0A, 0x32,
0x35, 0x35, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
It defines the binary content of a PNM file, eh? Those are very easy-to-read formats. No image loading library required.
0x50 0x36 is “P6”, which is an RGB PPM file. We can verify that with this:
> convert tux.png tux.ppm
> hd tux.ppm | head -3
00000000 50 36 0a 32 38 37 20 32-30 30 0a 32 35 35 0a ff P6 287 200 255
00000010 ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
00000020 ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
> head -3 tux.ppm
P6
287 200
255
Sure enough. So when you convert to .h
, you get the image encoded as a PPM binary file. After the ASCII header (“P6 … width … height … max_color_value”), the image data is just packed 8-bit RGB values (RGBRGBRGB…). This PPM (P6) format contains RGB pixels but no alpha channel. Viewing tux.ppm
in an image viewer converts that the alpha channel has been stripped.
> display tux.ppm
However, there is a PNM format that does support an alpha channel: PAM. So let’s convert to that:
> convert tux.png tux.pam
> hd tux.pam | head -7
00000000 50 37 0a 57 49 44 54 48-20 32 38 37 0a 48 45 49 P7 WIDTH 287 HEI
00000010 47 48 54 20 32 30 30 0a-44 45 50 54 48 20 34 0a GHT 200 DEPTH 4
00000020 4d 41 58 56 41 4c 20 32-35 35 0a 54 55 50 4c 54 MAXVAL 255 TUPLT
00000030 59 50 45 20 52 47 42 5f-41 4c 50 48 41 0a 45 4e YPE RGB_ALPHA EN
00000040 44 48 44 52 0a ff ff ff-00 ff ff ff 00 ff ff ff DHDR
00000050 00 ff ff ff 00 ff ff ff-00 ff ff ff 00 ff ff ff
00000060 00 ff ff ff 00 ff ff ff-00 ff ff ff 00 ff ff ff
> head -7 tux.pam
P7
WIDTH 287
HEIGHT 200
DEPTH 4
MAXVAL 255
TUPLTYPE RGB_ALPHA
ENDHDR
So after the text header (“P7…ENDHDR”), the image data is packed 8-bit RGBA values (RGBARGBA…).
After parsing the ASCII header off of a PAM, you can just fread()
the binary data in from a file and you’re ready to stuff it into an OpenGL texture with glTexImage2D()
(or glTexSubImage2D()
).