Saturday, April 11, 2009

Revisiting the Carousel

What's the difference between the two QVGA carousel implementations above? And what about the two VGA implementations below?

The top carousel icons look much better than the ones below, especially the ones with round shapes. What's the difference? While the images at the bottom carousel are regular Windows icons drawn from an image list container, the images at the top carousel are PNG images drawn using the IImage object. These PNG files were created with an "alpha channel", an extra byte of information that specifies how transparent each pixel is. Contrary to Windows CE icons which support only the concept of full transparency or full opaqueness, an alpha value determines how transparent each pixel is, so it can blend with the background and create very smooth transitions (so much nicer and easier on the eye). Using the right tools (these icons were produced using Axialis Icon Workshop), you can easily create these images and render them on the device screen.

The sample project (CarouselDemo2) illustrates how this can be implemented in code. First, I removed all the icon-related code and added two new classes (both on the image.h file): CImage and CImageArray. The first class encapsulates an IImage object and provides minimal services for loading the image from resources and drawing it on a given DC. The second class merely groups instances of the first in an array for convenience.

The great thing about IImage is that it allows us to load a raw byte stream of data making up a recognizable bitmap (more codecs can be added) and transforms it into a usable bitmap (not an HBITMAP, mind you). The supported image formats include JPEG, GIF and PNG with the nice alpha channel feature. All you have to do is load the image and draw it. Simple!

Well, not so fast... Really: it's dreadfully slow! If you run the new demo application you will see what I mean: the carousel scrolls like mud.

I previously had a similar experience where using IImage::Draw on a graphics-intensive GDI application proved impossible to use. The solution was to pre-render the PNG files (no transparencies here) to an HBITMAP and cache them, so I was not really surprised that the painting would be slower (but not that slow!). Is there any way around it? Hopefully yes, and I will write about it (or about my failure to achieve it) on my next blog post.

No comments: