Embedding PNG Images
From WxWiki
Contents |
[edit] Embedding PNG images into executables
XPM graphics files are really simple to embed into C++ source files, because they are made of plain C code, and you don't need to convert them (just #include them). The bad thing about XPM inclusion is the inflating of executables size and the lacking of alpha transparency.
PNG files do support alpha transparency, but are more difficult to embed, because we need to convert them into a C vector.
[edit] bin2c
First of all, you will need a program to convert the PNG binary files into a C vector, like:
static unsigned char myimage_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
// ...
};
You can use a small program to do this converting for you:
- Embedding_PNG_Images-Bin2c In C, (slightly modified version using header guards)
- Embedding_PNG_Images-Bin2c In Perl
- Embedding_PNG_Images-Bin2c In PHP
- Embedding_PNG_Images-Bin2c In Python
[edit] png2wx
png2wx is an alternative which also embeds files as a C string, but does so in a more compact way, which is available as a perl script; a python version is also available, but it is a lot slower than Perl. The utility creates a .cpp file containing the images (provided directly as wxBitmap *) and a .hpp for making the names available to other .cpp files. (The -M flag allows you to specify a custom reinclusion guard name.)
png2wx.pl -C images.cpp -H images.hpp -M IMAGES_HPP images/*
Although it is called png2wx, it just embeds any files you specify (images/* in this case) and the rest is up to the wxWidgets image handlers.
[edit] wxInclude
This tool will enable you to convert more images into one header.
Example:
wxInclude.exe --const --input-file=mydata1.bin --input-type=.png --input-type=.bmp --output-file=myheader.h mydata2.bin myimage.png
Most usefull is --input-type=.png this will convert all png files in the directory.
You can get the source code and static linked windows executable here.
[edit] Including
Once you have converted your graphics files with bin2c, you need to include them into your source code, e.g.:
#include <myimage_png.cpp>
For converting the images at runtime, you might use the wxMemoryInputStream class:
wxMemoryInputStream istream(myimage_png, sizeof myimage_png); wxImage myimage_img(istream, wxBITMAP_TYPE_PNG);
Or you can define a simple inline function like in your header file:
#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name ## _png, sizeof(name ## _png))
inline wxBitmap _wxGetBitmapFromMemory(const unsigned char *data, int length) {
wxMemoryInputStream is(data, length);
return wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1);
}
That's all! :)
[edit] Notes
Remember to add the support for the PNG format in your wxApp::OnInit() function:
wxImage::AddHandler(new wxPNGHandler);
This technique of embedding a PNG is also used by the Audacity sound editor (latest CVS only). It has the bin2c code built into it. It uses wxWidgets code to combine and split pngs, so that a theme consists of a single large png rather than many small ones.
[edit] Authors
Sandro Sigala <sandro AT sigala DOT it>
Nicola Leoni <nicola AT exilo DOT net>
