Click here to Skip to main content
15,070,680 members
Articles / Programming Languages / C#
Article
Posted 27 Jul 2007

Stats

62.5K views
559 downloads
17 bookmarked

Converting a BMP picture to WBMP format

Rate me:
Please Sign up or sign in to vote.
2.38/5 (5 votes)
27 Jul 2007CPOL3 min read
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:

C#
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);.

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sajjitha Gunawardana
Web Developer
Sri Lanka Sri Lanka
coding in C# C++ C

==============================================

Code in English, not Gibberish Smile | :)

Comments and Discussions

 
Questionwbmp to bmp? Pin
Huisheng Chen27-Apr-09 18:29
MemberHuisheng Chen27-Apr-09 18:29 
QuestionFara76 - where is it wrong? Pin
roonui7-Aug-07 21:05
Memberroonui7-Aug-07 21:05 
AnswerRe: Fara76 - where is it wrong? Pin
roonui8-Aug-07 0:19
Memberroonui8-Aug-07 0:19 
QuestionCan you please explain a part of your code please? Pin
Fara761-Aug-07 11:44
MemberFara761-Aug-07 11:44 
AnswerRe: Can you please explain a part of your code please? Pin
Fara761-Aug-07 11:52
MemberFara761-Aug-07 11:52 
GeneralRe: Can you please explain a part of your code please? Pin
Sajjitha Gunawardana2-Aug-07 14:42
MemberSajjitha Gunawardana2-Aug-07 14:42 
GeneralRe: Can you please explain a part of your code please? Pin
Fara762-Aug-07 15:56
MemberFara762-Aug-07 15:56 
GeneralRe: Can you please explain a part of your code please? Pin
Sajjitha Gunawardana2-Aug-07 16:35
MemberSajjitha Gunawardana2-Aug-07 16:35 
Generalnew code doesn't work Pin
todd_yx28-Jul-07 22:59
Membertodd_yx28-Jul-07 22:59 
GeneralRe: new code doesn't work Pin
Sajjitha Gunawardana29-Jul-07 5:17
MemberSajjitha Gunawardana29-Jul-07 5:17 
GeneralRe: new code doesn't work Pin
todd_yx29-Jul-07 22:19
Membertodd_yx29-Jul-07 22:19 
GeneralRe: new code doesn't work Pin
Sajjitha Gunawardana30-Jul-07 4:41
MemberSajjitha Gunawardana30-Jul-07 4:41 
GeneralRe: new code doesn't work Pin
todd_yx1-Aug-07 0:27
Membertodd_yx1-Aug-07 0:27 
GeneralRe: new code doesn't work Pin
kjaway10-Aug-09 22:33
Memberkjaway10-Aug-09 22:33 
GeneralThx a lot Pin
todd_yx28-Jul-07 13:56
Membertodd_yx28-Jul-07 13:56 
GeneralOne Suggestion Pin
Willi Deutschmann28-Jul-07 8:56
MemberWilli Deutschmann28-Jul-07 8:56 
GeneralRe: One Suggestion Pin
Sajjitha Gunawardana28-Jul-07 9:27
MemberSajjitha Gunawardana28-Jul-07 9:27 
QuestionWonderful program! And one more question Pin
todd_yx27-Jul-07 19:32
Membertodd_yx27-Jul-07 19:32 
AnswerRe: Wonderful program! And one more question Pin
Fara7628-Jul-07 1:15
MemberFara7628-Jul-07 1:15 
GeneralRe: Wonderful program! And one more question Pin
Sajjitha Gunawardana28-Jul-07 4:47
MemberSajjitha Gunawardana28-Jul-07 4:47 
AnswerRe: Wonderful program! And one more question Pin
Sajjitha Gunawardana28-Jul-07 4:43
MemberSajjitha Gunawardana28-Jul-07 4:43 
GeneralRe: Wonderful program! And one more question Pin
Fara7628-Jul-07 12:13
MemberFara7628-Jul-07 12:13 
GeneralRe: Wonderful program! And one more question Pin
Sajjitha Gunawardana29-Jul-07 6:57
MemberSajjitha Gunawardana29-Jul-07 6:57 
Generalthx a lot Pin
todd_yx27-Jul-07 14:48
Membertodd_yx27-Jul-07 14:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.