Introduction
This project contains a class which provides a wrapper around the lodepng
library provided by Lode Vandevenne. Its primary purpose is to provide
tools to easily read and display PNG files, for C++ programmers who write in
raw WinAPI.
Background
The PNG image format is an excellent format to use for images which
are to be included in programs; it provides lossless compression which
gives dramatically smaller files than BMP, with far better
image quality than JPG. However, the normal WinAPI libraries cannot
handle PNG files.
Recently, I was creating a game which used sprite-based graphics; I wrote
it initially using the sprite images from the ancient Nethack game; it stored
its sprites in a 1.2MB file containing over 1000 sprites! It worked well
and was easy to use, but the same file in PNG format was 155KB ... much better!!
I started researching PNG libraries, and discovered Lode Vandevenne's
LodePNG library, which comprised a
single 6600-line C++ source file and a header. However, I had some problems
with it. The first was that he did not have any examples which showed how to
access his resulting data from a WinAPI application; all his rendering
examples were OpenGL or SDL. Also, it required creating two vector objects
for each file, which was awkward when several files were involved.
So, after doing some research online, I found a way to convert his BMP vector
into an HBITMAP
reference which can be used by BitBlt
and other normal
WinAPI
GDI functions, and that worked quite well.
With all the required tools in hand, I then wrapped all these functions
into a simple class which makes access to lodepng
quite trivial.
The enclosed demo program will demonstrate how to use this library.
Using the Code
#include "lode_png.h"
#define SPRITE_WIDTH 32
#define SPRITE_HEIGHT 32
LodePngWin32 pngSprites("tiles32.png", SPRITE_HEIGHT, SPRITE_WIDTH) ;
LodePngWin32 pngFireCat("FireCat.png") ;
typedef struct sprite_sel_s {
uint column ;
uint row ;
} sprite_sel_t ;
static sprite_sel_t const sprite_selection[4] = {
{ 6, 13 }, { 8, 20 }, { 23, 14 }, { 39, 0 }, } ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
pngSprites.render_bitmap(hdc, 50, 100, sprite_selection[0].column, sprite_selection[0].row) ;
pngSprites.render_bitmap(hdc, 50, 200, sprite_selection[1].column, sprite_selection[1].row) ;
pngSprites.render_bitmap(hdc, 120, 100, sprite_selection[2].column, sprite_selection[2].row) ;
pngSprites.render_bitmap(hdc, 120, 200, sprite_selection[3].column, sprite_selection[3].row) ;
pngFireCat.render_bitmap(hdc, 200, 50) ;
EndPaint (hwnd, &ps);
return 0;