Choosing Appropriate Bitmap Formats and SizesWorking with bitmap images is common both for low-level graphics work as well as high-level user interface design. Most user interface frameworks offer some notion of a PictureBox control that can display bitmaps, and lower-level graphics libraries deal mainly with bitmap-level operations. Many kinds of interesting applications work with bitmap images, such as street maps, medical images, real estate photos, and play fields for games to name only a few. When working with bitmap data, it is important to think of both the file representation of an image as well as the in-memory storage of image data. Several different file formats exist for storing and streaming bitmap data, each with specific strengths and weaknesses. Regardless of the file format used, the in-memory representation of bitmaps is usually as a matrix in memory corresponding to the pixel dimensions of the image; it is a noncompressed format suitable for quick use with the graphics hardware and the underlying operating system. Size Does MatterThe first question to ask when looking at bitmap data for mobile devices is what are the physical pixel dimensions of the images you are proposing to bring down to the devices and load into memory?To keep the math simple, let's assume we are dealing with square-shaped bitmaps. A 1-megapixel image would translate to 1,000 pixels x 1,000 pixels. This resolution is far larger than the screens of most mobile devices and until recently larger than most desktop screens (1024 x 768 is only 786,432 pixels). Even inexpensive digital cameras today take photographs in excess of 2 megapixels, 4 megapixel cameras are not uncommon, and the pixel count keeps climbing every year.Physical displays with many pixels consume more power than lower-resolution screens, cost more, take up more space, and are more fragile. In addition, a larger screen means larger amounts of device memory and processing power devoted to graphics. Doubtless over time, mobile device screens will continue to get more pixels but there are good reasons to believe that the resolution will continue to lag both digital camera output and desktop display resolutions. Even assuming a large mobile device display of 500 x 500 pixels, it will contain only 250,000 pixels. This is one fourth of a 1-megapixel image and only one sixteenth of a 4-megapixel image. To approach this from another direction, to fit a 4-megapixel image on 240 x 320 Pocket PC display (76,800 pixels) would require throwing out a staggering 98 percent of the pixels in the image. Similarly, a 2-megapixel image would require throwing out 96 percent of the pixels to fit on the same Pocket PC screen, and a 1-megapixel would contain a 92 percent excess of pixels.Why does this matter? Several reasons:Download size If your application does not need the extra pixels, what is the point in downloading them? Downloading larger files takes more time and often costs more money. Mobile device Web applications specifically cater to reduced screen sizes by having lower-resolution images. This makes sense for rich on-device applications as well.On-device storage size If your mobile device application downloads a large image, you will need to store it somewhere. This typically means either storing it in a RAM-based file system or in flash storage. In either case, unnecessarily large images require extra read and write time and use up space that could either be used for more images or other data. Would you rather have a single 4-megapixel image on your device or dozens of screen-sized images?In-memory representation This is perhaps the most significant aspect to consider. If your mobile application loads a 4-megapixel image into memory, it is creating an in-memory bitmap with 4 million pixels. How often do you declare and use an integer array of 4 million items in your application? That is an awful lot of limited availability program memory to use and almost certainly significantly larger than your loaded code and all other application state. Regardless of the efficiency of the file compression used an in-memory bitmap is just that, a mapping of image bits into memory. Further, if you are using an image file format that requires mathematically complex algorithms to achieve high compression ratios, this math will need to be done to uncompress the images as well, meaning that this will cost your application dearly in performance. Having large bitmaps loaded into memory is a great way to use up all the free memory on a device and either drive the performance of your mobile application right into the ground or cause your application to fail because it has run out of memory. The moral of the story here should be clear: It does not make sense to use images with pixel counts larger than your device's screen size. These images will be slow to transfer, will need a lot of memory to store and load into memory, and will need to be transformed down into a size that fits on the mobile device's screen regardless. Paying attention to your mobile device's available screen size and choosing image sizes that relate to the space you have to work with makes the most sense. If your application will have a PictureBox that is 120 x 120 pixels, use an image of that size.Most real-world images are far larger than mobile devices can deal with effectively. How should this disparity be addressed? This is a good opportunity for doing processing off-device to make the on-device experience better. If your images are static images that are known at design time, shrink them down into the actual device resolutions you will be displaying. If your application is dealing with dynamic images, use a server to do the image resizing. A server could dynamically load and resize a large image to a device-sized image if need be but it is far more efficient and scalable to do this work once and cache the results on the server for future use. Because the device-sized images are small, it only requires a trivial amount of extra server storage space to store them along side full-sized images. The easiest time to do this work is when the images are uploaded to a server.If you try to load large-resolution images into a mobile device application, you will create severe memory pressure. Avoid doing this because end users will see no benefit from images that are larger than their device's screen resolution. Instead, make sure that the digital images that do go onto devices are of a resolution that matches the screen real estate they will be displayed on. This will perform much better. So Many File Formats, So Little TimeThere are many file formats available for digital images. Each has benefits and limitations. Here are descriptions of some of the most common formats that are often supported on mobile devices. *.JPG/*.JPEG Files (Joint Photographic Experts Group)True to their name, JPEG files excel at storing photographic and real-world images. JPEG is a variably lossy compression format meaning that you can generally achieve great size-compression benefits by accepting a bit of distortion to the image. All the JPEG photographs you take with common digital cameras use lossy compression. This is why you can fit a stunning looking 3-megapixel image into a 600KB file. More-sophisticated painting programs will let you set the JPEG compression ratio and enable you to explicitly trade off fidelity for size reduction. Often you can get very good looking photographs at very reasonable sizes. A Pocket PC screen resolution-sized photograph may compress down to below 20KB and still look great using JPEG file formats.Because JPEG is meant to work with real-world images, it will usually not yield the best results for computer-generated raster images such as text on screen snapshots, sharp lines, and sharp color transitions. For these kinds of images, you will generally want to choose a nonlossy format. *.PNG (Portable Network Graphics)PNG is a relative newcomer to file formats but is fast gaining acceptance as an excellent file format for images. The effort to create the PNG format arose as a response to some intellectual property rights issues with the *.GIF format*. PNG files offer excellent nonlossy compression for digital images. If your platform supports *.PNG images and you need nonlossy compression, this is the format for you. The *.PNG format offers better compression than *.GIF in many cases and is a better choice if both are available. *.GIF (Graphics Interchange Format)Think of the GIF format as the popular predecessor to PNG. GIF files offer nonlossy compression as well but are limited to using 256 colors. Because of this limitation, the GIF format is not appropriate for storing photographic images. *.GIF files were heavily used in Web pages in the early years of popular Internet usage and for this reason still have a wide following. *.BMP (Bitmap Files)Bitmap files are noncompressed image data. They store data in a format similar to the in-memory bitmap format. Other than not requiring much work to decompress, there are no particular advantages of using *.BMP files other than wide availability.Chapter 13, "Step 2: Design the Right User Interface." What to Do If the Mobile Device Is the Source of the High-Resolution ImageMany mobile phones today come with digital cameras capable of taking photographs. Some of these images may be in excess of 1 megapixel (for example, 1,000 x 1,000 pixels), and doubtless this trend will continue upward. Like photographs taken by digital cameras, the images are of far higher resolution than the devices are capable of usefully displaying on their screens; the images are intended for viewing on larger-screened devices (desktop computers) or for printing. It is very wasteful to load and keep a bitmap of this size in memory, but because of latency and connectivity issues it does not make sense to send the picture to a server to be reduced and sent back down to the device either. The solution to work with a large resolution image and still efficiently manage memory on the device is as follows:Load the high-resolution image into memory. Note: If the image is large enough, this may not actually be possiblein which case, a smaller resolution image must somehow be created before even it can be loaded, possibly when the image itself is acquired. A lower resolution image can be saved along with the full-sized image.Immediately make a reduced-sized copy of the image in memory that compresses the image into the dimensions it will be displayed in. This will create an in-memory bitmap image with a much lower pixel count.Dispose and release the original high-resolution bitmap as soon as possible.If your runtime framework supports saving images, it may make sense to save and cache the reduced size image for future use so that your mobile application does not need to go through the temporary memory and processor usage spike of loading the large image. The important thing is to keep the steady-state amount of memory your mobile application is using down to a minimum, and this means not keeping any extra pixel data in memory that you cannot display. For digital photographs, this can save megabytes of program memory and on mobile devices this will have a significant impact on the performance of your application. |