Reading image header file .h, hex dumps and others

#1

Hi, I’m currently starting to study C ++ and OpenGL ES, and I would like to know and if it’s possible, how do I read an image in header .h (array of color bytes) generated from converting a png with imagemagick with transparency (if it works, I don’t know yet).
(ImageMagick: convert * .png -> * .h)

If this information makes a difference, I’m currently using FreeGLut -3.2.1 (2019), C ++ 11, GLAD, and GLM.

I’ve been researching things like using xxd (generate hex dump file) to embed features like music (.ogg), etc. Does it work on OpenGL too?

Sorry for noob questions

#2

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()).

2 Likes
#3

If I could give more than 1 like in your answer I would give. But what about xxd and reading audio? Libogg and Libvorbis is required or can i use the hex dump (i think it makes it like a assembly file, at least i think) embed on OpenGL app? And taking the opportunity to ask one (or two…) more question, what is the difference between Core and Compatibility, while I chose the GLAD version and GL extensions, this option was there, the new FreeGLut that looks like it has android support works is using until GLES2, should I choose Core or Compatibility (I’ll be using it for Desktop too)?

EGL 1.5 supports GLES2 (2.0)?

And sorry for my english if its something wrong or strange.

Anyways thanks!

#4

These forums are for posting questions related to Khronos APIs and formats such as OpenGL, OpenGL ES, Vulkan, and glTF.

So you need to look for elsewhere for that info.

Core and Compatibility are types of OpenGL Contexts that you can create. Compatibility includes all features added to OpenGL. Core removes some of the old, deprecated, legacy features.

Which kind of context is created is up to the application.

You can read more about this here: OpenGL Context

Not necessarily. These are two different APIs.

EGL is a window system interface layer, which can be used to create OpenGL ES (and OpenGL) contexts. The min/max version supported by one is not linked to the min/max version supported by the other AFAIK.

1 Like
#5

This topic is interesting, but xxd from vim, isn’t more easy? xxd is for any file i think; not just audio or text…

Why…

convert -i image.png ‘>’ image.h (resulting pnm)
convert image.png ‘>’ image.pam (then parse the ascii)

?

Why just don’t use…

convert image.png ‘>’ image.pam
xxd -i image.pam ‘>’ image.h

or

xxd -i image.png > image.h

?

@Edit: I just tried to convert the files above, but I don’t tried to make GL read it yet…

A heart (good design and big,rgb alpha transparency) 256x256 with 20kb png to header making this way, I got a header file bigger than just:

convert png to header

png: ~20kb
xxd png to header directly: ~58kb
imageconvert header generated: ~1.2mb (pnm)
png converted to pam, then converted to header with xxd: ~1.5mb (direct pam?)

If this solution works as fine like Dark_Photon solution…
It create big files, probably you wanna make this highly embed resources, right? Are you sure about this? Binaries will be big.

And imagemagick can extract to header just alpha and rgb, I don’t know if this create a solution for PNM, but u can try:

(need look the doc, i don’t know if the arguments is correct)

convert image.png -rgb imagergb.h
convert image.png -alpha imagealpha.h

and imageconvert can attach* images too, i don’t know about headers.

You can take a look and join imagergb.h + imagealpha.h

1 Like
#6

I didn’t know imagemagick can extract to alpha or color header specifically.

I went to look at the documentation again, and it puzzled me:

From imagemagick:

  • PNM is a family of formats supporting portable bitmaps (PBM), graymaps (PGM), and pixmaps (PPM). There is no file format associated with pnm itself. If PNM is used as the output format specifier, then ImageMagick automagically selects the most appropriate format to represent the image. The default is to write the binary version of the formats. Use -compress none to write the ASCII version of the formats.

From netpbm doc:

  • npm - netpbm format - The PNM format is just an abstraction of the PBM, PGM, and PPM formats. I.e. the name “PNM” refers collectively to PBM, PGM, and PPM.

  • PPM - Netpbm color image format

  • pgm - Netpbm grayscale image format

From Netpbm PGM page:

  • One official variant of PGM is the transparency mask. A transparency mask in Netpbm is represented by a PGM image, except that in place of pixel intensities, there are opaqueness values.

Imagemagick choose PNM cause it detect automatically a color image, but it make a just RGB no alpha file

Maybe it’s possible to use PGM and PPM and join them together like you said with imagemagick (or just copy-paste the hex array on files)?

Anyway, thanks you both for the help!