Monday, March 16, 2009

IImage::Draw

Drawing PNG images on the screen has become quite easy since Microsoft released the imaging library for Windows Mobile devices. Christopher Fairbairn illustrated the technique on one of his excellent blog posts where he illustrates the process, from acquiring the bitmap data to rendering it on the screen. As he points out, if you load a PNG file with an alpha layer, the transparency will be correctly painted to the image creatin all sorts of nice visual effects. But...

... this is a very expensive operation! In fact, IImage::Draw is slower than painting a non transparency bitmap using the regular BitBlt API. If you need raw performance (like when you are repeatedly painting lots of these to the screen, even with a double buffer) yo will get a terrible performance hit. I found out about this in my map rendering scenario, while adding KML-encoded layers. As the number of bitmaps grows, the rendering speed degrades very rapidly to the point where it becomes unusable. What can you do?

My solution was to pre-render the PNG file into a regular GDI bitmap (adding a white background) and then using the BitBlt API to render it. The performance was back at the expense of some unsightly white backgrounds on my map icons... Seems like this is going to be the solution if I want to stick with the GDI.

P.S: The white box issue was neatly solved by rendering the PNG against a Magenta (RGB(0xff, 0, 0xff)) background and using the TransparentImage API.

1 comment:

max said...

Can you provide a source code?