How to embed a file into an executable?

Anne Quinn picture Anne Quinn · Sep 2, 2011 · Viewed 25.8k times · Source

I have a small demo executable wrote in C++ that depends only on one 5kb PNG image being loaded before it can run, which is used for a pixel text I made. Because of this one file, I would need to give out a ZIP archive instead of just one executable file, which creates enough friction between download and 'play' that I believe would dissuade some from trying it out.

My question is, is there anyway to embed the PNG file (and any other file really) into the Executable or source code so that it is a single file, and the executable can use it?

I have the ability to parse the PNG as a byte stream, so it does not need converted to pixel data.

Thanks in advance! (Other questions with a similar title to this exist, but they and their answers seem to get into more specific issues and weren't very helpful)

edit:The compiler is Visual C++ 2010 and this is on Windows (though I would want to avoid windows specific utilities for this)

edit2: Alf's answer seemed like the most portable method, so I quickly wrote a function to parse the PNG file into a TXT or header file that could be read as a unsigned char array. It appears to be identical in this form to the PNG file itself, but my png loader won't accept the array. When loading it from memory, the PNG parser takes a (void * buffer, size_t length) if it matters.

The code if you wanted to see, but I'll still accept other answers if you think they're better than this method:

void compileImagePNGtoBinary(char * filename, char * output){

    FILE * file = fopen(filename, "rb");
    FILE * out = fopen(output, "w");

    unsigned char buffer[32];
    size_t count;
    fprintf(out, "#pragma once \n\n static unsigned char TEXT_PNG_BYTES[] = { ");
    while(!feof(file)){
            count = fread(buffer, 1, 32, file);

            for(int n = 0; n < count; ++n){
                    fprintf(out, "0x%02X, ", buffer[n]);
            };
    };
    fprintf(out, "};");
    fclose(file);
    fclose(out);

};

Final Edit: ImageMagick which Alf also mentioned did exactly what I needed of it, thanks!

Answer

Cheers and hth. - Alf picture Cheers and hth. - Alf · Sep 2, 2011

A portable way is to define a function like

typedef unsigned char Byte;

Byte const* pngFileData()
{
    static Byte const data =
    {
        // Byte data generated by a helper program.
    };
    return data;
}

Then all you have to do is to write a little helper program that reads the PNG file as binary and generates the C++ curly braces initializer text. Edit: @awoodland has pointed out in comment to the question, that ImageMagick has such a little helper program…

Of course, for a Windows-specific program, instead use the ordinary Windows resource scheme.

Cheers & hth.,