Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Converting a BMP picture to WBMP format

0.00/5 (No votes)
27 Jul 2007 1  
This program converts a BMP picture to the WBMP format used in wireless devices.

Screenshot - bmptowbmp2.jpg

Introduction

This code will load a picture and convert it into WBMP format. The first version of the program supported only monochrome BMPs with width, height < 127. Currently, you can load color pictures as well, and pictures with width, height > 127.

Background

WBMP is an image format used in wireless devices. The pictures in the WBMP format are saved in bit format. That is every pixel of an image is saved as 1 bit. Thus, an 8 x 8 pixel image will require only 64 bits (8 bytes). The limitation of this format is that it can save images in Black and White only (no support for color or grey scale). Thus, if you load any non-monochrome picture, it will be internally converted to monochrome using Dithering Algorithms (using the AForge library for this purpose).

Using the code

The main part of this program is concerned with reading a pixel from a black and white BMP picture, checking whether each pixel is either black or white, and then writing either a '0' or '1' into the output WBMP. Thus, every 8 pixels of the input BMP will get compressed into one byte (8 bits), which is then written into the WBMP file.

If for example the first pixel in the BMP is black, a '0' is written into the first location of the output byte. If the second pixel in the BMP is white, a '1' is written into the second location of the output byte. If the third pixel is white, a '1' is written to the third location of the output byte...

The above is repeated until the whole output byte has been written to (which will correspond to 8 pixels in the input BMP). This output byte is then written to the WBMP file. The whole process is then repeated until all the pixels in the input BMP has been 'compressed' and written into the output WBMP file.

The original code for converting the monochrome image to WBMP looks as follows:

for (int y = 0; y < inputBmp.Height; y++)
{
    byteLocation = 0;
    data = 0;
    for (int x = 0; x < inputBmp.Width; x++)
    {
        Color color = inputBmp.GetPixel(x, y);
        byte BW = (byte)((color.R + color.G + color.B) / 3);
        //reset byteLocation every 8 bits
        if (byteLocation > 7) byteLocation = 0;
        bool black = false;
        if(BW > 125)
        {
            black = true;
        }
        switch (byteLocation)
        {
        case 0:
            if (black)
            {
                data |= (byte)128;
            }
            break;
        case 1:
            if (black)
            {
                data |= (byte)64;
            }
            break;
        case 2:
            if (black)
            {
                data |= (byte)32;
            }
            break;
        :
        :
        case 7:
            if (black)
            {
                data |= (byte)1;
            }
        // every 8 bits write the data to the output file
            bw.Write(data);
            data = 0;
            break;
        }
    byteLocation++;
    }

    // if at end of a line we have some remaining bits to be written, write it here
    // this will happen if bmp width is not a multiple of 8.
    if (byteLocation != byteLength + 1)
    {
    bw.Write(data);
    }
}

After receiving some feedback from 'Willi Deutschmann', the above code was simplified to the following. Now, instead of a switch structure, we are using this single line of code: data |= (byte)(128 >> byteLocation);.

for (int y = 0; y < inputBmp.Height; y++)
{
    byteLocation = 0;
    data = 0;
    for (int x = 0; x < inputBmp.Width; x++)
    {
        Color color = inputBmp.GetPixel(x, y);
        byte BW = (byte)((color.R + color.G + color.B) / 3);
                        
        //reset byteLocation every 8 bits
        if (byteLocation > 7) byteLocation = 0;
                        
        if(BW > 0)
        {
            data |= (byte)(128 >> byteLocation);
        }

        // every 8 bits write the data to the output file
        if (byteLocation == 7)
        {
            bw.Write(data);
            data = 0;
        }        
        byteLocation++;
    }   

    // if at end of a line we have some remaining bits to be written, write it here
    // this will happen if bmp width is not a multiple of 8.
    if (byteLocation != byteLength + 1)
    { 
        bw.Write(data);
    }
}

Points of Interest

I am not sure what the proper method of writing bits into a byte in C# is. I guess in C, for example, there is an option for specifying bit fields in a structure and then writing to every bit separately. So what I am doing above is using a bitwise OR operation in C# to write to the separate bits of a byte. In the earlier version, this was done as follows: to write a '1' into the bit location 8 of a byte, I used something like data |= (byte)128;. To write a '1' into the bit location 7 of a byte: data |= (byte)64; etc. In the new code, this has been modified to data |= (byte)(128 >> byteLocation);.

To convert a color image to monochrome, use the AForge Library for which a sample program is available here @ http://www.codeproject.com/cs/media/Image_Processing_Lab.asp.

You can check whether a WBMP image created is alright using any of the online emulators. First, create a .wml file with the WBMP image. Upload the WML file and the WBMP image to a website, and give the URL of the .wml file to the emulator. Several sample WBMP pictures created with this application can be accessed @ http://sajjitha.atspace.com/lake2.wml and http://sajjitha.atspace.com/forest.wml.

Limitation / Modification...

The program has been tested for monochrome and Color images. Several WBMP files produced by this application were uploaded into a WAP emulator and they displayed OK...

History

  • 07/29/2007: Support for color images and images with width, height > 127.
  • 07/31/2007: Corrected a bug which gave a wrong output when image width, height > 127.
  • Hopefully the program works OK now... :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here