Windows CE Blog        Embedded Product Design Services

Nov/09

19

Creating an effective image viewer in Windows CE

There are some cases where we may need to develop a DLL or application to show the images on the devices. For example, an Image viewer will be needed to show the picture after taking a snap shot from the camera using a direct show camera application. Windows Mobile supports the image viewer for this purpose, However if you are developing a custom camera application in Windows CE/Windows Mobile, you have to show the captured image with a custom developed image viewer. There you may need additional image manipulation functionality like zooming, rotation and cropping etc. Unfortunately Windows CE 6.0 doesn’t have an image viewer application at all. But Windows CE supports Imaging APIs to handle the various file types like JPG, BMP, TIFF and GIF etc…

Effective way of handing the JPEG images on Image viewer

Imaging APIs are accessed through COM interfaces. To Load the image you have to use IImagingFactory Interface with the class ID CLSID_ImagingFactory. Following code snippet show the procedure to load the imaging COM interfaces.

CoCreateInstance (CLSID_ImagingFactory, NULL,CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&m_pImgFactory). The m_pImgFactory is the pointer to the IImagingFactory.

Opening an image file

Use the IImagingFactory ::CreateImageFromFile(const WCHAR* filename, IImage** image) to open the file.

Simple way to draw the Image on the Screen

We can use the IImage :: Draw( HDC hdc, const RECT* dstRect,OPTIONAL const RECT* srcRect) to draw the image on the screen with the required dstRect size. But when our application Menu area may over write some part of the image, we may need to redraw the image in WM_PAINT on our window proc. IImage::Draw() function will decode the image and draw every time, while calling the function. This makes your application slow, while clicking the Menu.

To avoid this, we can use the Image::SetImageFlags(ImageFlagsCaching) to cache the bitmap area and to reuse it for the next time. The disadvantage is, IImage::Draw() may fail because of  insufficient memory to cache the higher Mega Pixel files. This will happen in Windows Mobile (virtual memory limitations for each process). So we need to find the alternate solution, that should be effectively handling the memory and to maintain the performance.

Effective way to draw the image on the screen

The Effective way is, creating the bitmap for the exact required screen size once and uses it for several times. Following are the steps to create and draw the bitmap.

  • Passing IImage interface to IImagingFactory::CreateBitmapFromImage(IImage* image, OPTIONAL UINT width, OPTIONAL UINT height, OPTIONAL PixelFormatID pixelFormat,  InterpolationHint hints, IBitmapImage** bitmap) will provide IBitmapImage. We can create the bitmap to the required size. (ie) your required screen size. It will consume memory only to the width, height and the required pixelFormat . Using this you can show higher Mega pixels images.
  • Using this IBitmapImage::LockBits(const RECT*rect,UINT  flags,  PixelFormatID pixelFormat, BitmapData*   lockedBitmapData) we can get the BitmapData class, containing the width, height, scan0 ( bitmap area starting address) and other necessary data. Release the bitmap area by calling IBitmapImage::UnlockBits function.
  • Using this BitmapData information, we can create the BITMAPINFO structure as follows:

m_pBitMapInfo =(BITMAPINFO*) new char[sizeof(BITMAPINFO)+ 4];

//Now write the BITMAPINFOHEADER

m_pBitMapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

m_pBitMapInfo->bmiHeader.biWidth = m_Bitmapdata.Width;

m_pBitMapInfo->bmiHeader.biHeight = -(LONG)m_Bitmapdata.Height;

m_pBitMapInfo->bmiHeader.biPlanes = 1;

m_pBitMapInfo->bmiHeader.biBitCount = 16;

m_pBitMapInfo->bmiHeader.biCompression = BI_BITFIELDS;

m_pBitMapInfo->bmiHeader.biSizeImage = m_Bitmapdata.Width*m_Bitmapdata.Height;

m_pBitMapInfo->bmiHeader.biClrImportant = 0;

m_pBitMapInfo->bmiHeader.biClrUsed = 1;

unsigned long *ptr = (unsigned long *)(m_pBitMapInfo->bmiColors);

ptr[0] = 0xf800;

ptr[1] = 0×07e0;

ptr[2] = 0×001f;

  • Passing the BITMAPINFO with BitmapData::scan0 to StretchDIBits function to draw the image. Since we have the bitmap data, we can simply redraw during the WM_PAINT without any image decoding process. It will avoid the unnecessary overhead of the application.
  • For zooming and panning process, we can simply create the bitmap for the necessary size and we can show the part of the image, also moving and showing the image seamlessly with above described APIs.

RSS Feed

4 Comments for Creating an effective image viewer in Windows CE

Rob E | January 4, 2010 at 3:37 am

Many thanks for this helpful article and code! Any ideas on how I can setup an array to hold the bytes of multiple bitmaps with different BPP?

Valter Minute | January 27, 2010 at 11:42 am

Hi Vinoth,
great description of an API that seems to be well “hidden” inside Windows CE!

Author comment by Vinoth - Microsoft Certified Technology Specialist | February 15, 2010 at 2:53 am

Hi Rob,
You have to pass required PixelFormatID as a 4th parameter to IImagingFactory::CreateBitmapFromImage() for the required bitmaps with different BPP.
See the following link to know the supported pixel formats.
http://msdn.microsoft.com/en-us/library/ms932259.aspx

As i have mentioned above, BitmapData::scan0 is containing the Bitmap data. you can maintain the array of bitmap pointer to hold the multiple bitmaps. Size of each bitmap is determined by the pixel format of corresponding bitmap.

Author comment by Vinoth - Microsoft Certified Technology Specialist | February 15, 2010 at 5:42 am

Hi Valter,
Thank you for your appreication.

Leave a comment!

<< Customizing Power Manager for SetSystemPowerState()

Handling Real Time Tasks in Windows CE >>

Find it!

 

e-con Systems is a leading Product Design services company drives a passion of Productizing ideas, e-con so far have developed Smart phones, PDAs, Industrial data loggers, Loyalty terminals, Point of Sale terminals and Reference platforms among others with OS focus on Windows CE 6.0, Windows Mobile and Linux 2.6.25.

e-con is popularly known for its Computer on Modules, Reference Designs and Camera Solutions among others...

Copyright © 2009 w w w . e - c o n s y s t e m s . c o m . | Download Comp any Profile | Sitemap  Windows Embedded Gold Partner