Click here to Skip to main content
12,300,245 members (45,516 online)
Click here to Skip to main content
Add your own
alternative version

Stats

133.3K views
35 bookmarked
Posted

Image Bit depth conversion from 32 Bit to 8 Bit

, 20 May 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
This article describes about image bit depth conversion from 32 bits to 8 bits.

Introduction

This article describes about image bit depth conversion from 32 bit to 8 bit. There are several methods for conversion. In this article, Indexed color and palette are used.

32 Bit to 8 Bit Conversion

There are several methods to convert to indexed color. Some methods are Dithering, Nearest Color, Adaptive or Optimized or Perceptual Palette, Standard Web Browser Palette etc. Here I am describing about Standard Web Browser Palette.

The Standard Palette (often called Web palette) always contains the same colors for any image. It is sometimes called 6-6-6, because it contains six standard evenly spaced colors for each of Red, Green, and Blue. Those 6x6x6 color combinations create 6x6x6 = 216 standard color combinations, which are used for any image.

The Standard Palette always contains combinations of the following 6 tones for each of the Red, Green, Blue primaries:

The 216 combinations of these 18 colors above (six shades of the three RGB colors, 6x6x6 = 216) produce the Standard web-safe palette. This Standard web-safe palette color shades are shown below:

Sample screenshot

First, we define a standard color table using those 6 colors.

const DWORD STANDARD_PALETTE[] = {00,51,102,153,204,255}
const INT STANDARD_COLOR_SIZE = 6;
const INT STANDARD_PALETTE_VAL_DIF = 51; 
// difference between two consecutive standard color Palette.

For 8 bit conversion, we must create a color table which is called as Palette color map. All possible combinations of Standard palette colors are entries in this table. Palette color map creation is shown below:

DWORD dwColorMapTable[216] = {0};
int  nColorMapIdx = 0;
for (int nBlueIdx = 0; nBlueIdx < STANDARD_COLOR_SIZE; ++nBlueIdx)
{
    for(int nGreenIdx = 0; nGreenIdx < STANDARD_COLOR_SIZE; ++nGreenIdx)
    {
        for(int nRedIdx = 0; nRedIdx < STANDARD_COLOR_SIZE; ++nRedIdx)
        {
            RGBQUAD objColor;
            objColor.rgbRed    = STANDARD_PALETTE[nRedIdx];
            objColor.rgbGreen = STANDARD_PALETTE[nGreenIdx];
            objColor.rgbBlue = STANDARD_PALETTE[nBlueIdx];
            objColor.rgbReserved = 0;
            memcpy(&dwColorMapTable[nColorMapIdx],&objColor,sizeof(RGBQUAD));
            ++nColorMapIdx;
        }
    }
}

After that, we can convert a 32 bit image file to 8 bit image file. For conversion, read each pixel data from input image data. Get Red, Green and Blue values from pixel. With these RGB values, calculate suitable color from STANDARD_PALETTE. Find suitable color from the Palette color map table. Set table map entry index to the output pixel value.

Cstring csInputFileName = "c:\\32BitImage.bmp";
Bitmap InputImage(csInputFileName,FALSE);
INT nImageHeight = InputImage .GetHeight();
INT nImageWidth = InputImage .GetWidth();
INT nPixelSize = nImageHeight * nImageWidth;
BYTE byBitsPerPixel = 32; // Input image Bits per pixel.
BYTE pixels = new BYTE[nPixelSize];
for(UINT nRow = 0; nRow < nImageHeight; ++nRow)
{
    for(UINT nCol = 0; nCol < nImageWidth; ++nCol)
    {
        Color objColorData;
        UINT i8bppPixel = nRow * nImageWidth + nCol;
        // Get pixel data from Input image.
        if(Ok != InputImage GetPixel(nCol,nRow,&objColorData))
        {
            printf("Get Image Pixel Failed.\n")
        }
        // Get RGB value from color data.
        int nRed = objColorData.GetRed();
        int nGreen = objColorData.GetGreen();
        int nBlue = objColorData.GetBlue();
        // Get Index of suitable color data in the palette table.
        UINT uRedValue = GetPixelValue(objColorData.GetRed());
        UINT uGreenValue = GetPixelValue(objColorData.GetGreen());
        UINT uBlueValue = GetPixelValue(objColorData.GetBlue());

        // Calculate Pixel color position
        // in the color map table using RGB values. 
        // Finally set this index in to the pixel data.
        UINT uPalettePos = uBlueValue*36+uGreenValue*6+uRedValue;
        pixels[i8bppPixel] =(BYTE)uPalettePos;
    }
}

GetPixelValue() returns appropriate pixel index value in the Standard Palette table. Implementation is shown below:

UINT GetPixelValue(UINT uPixelValue_i)
{
    UINT uRetValue = 0;
    UINT uPos = uPixelValue_i / PALETTE_VAL_DIF;
    if(0 == uPixelValue_i % PALETTE_VAL_DIF)
    {
        uRetValue = uPixelValue_i/PALETTE_VAL_DIF;
    }
    else
    {
        if(abs(uPixelValue_i - STANDARD_PALETTE [uPos]) > 
           abs(uPixelValue_i - STANDARD_PALETTE [uPos+1]))
        {
            uRetValue = uPos+1;
        }
        else
        {
            uRetValue = uPos;
        }
    }
    return uRetValue;
}

For viewing converted image:

  1. Create an output file.
  2. Write Bitmap header to the output file.
  3. Write pixel data to the output file.
  4. Close output file.

Good luck!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shanu K S
Software Developer NeST
India India
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalpixel data Pin
sandeeprattu1-Jul-09 21:18
membersandeeprattu1-Jul-09 21:18 
Questionconvert 16 bit to 8 bit? Pin
harshi_mm214-Feb-08 0:34
memberharshi_mm214-Feb-08 0:34 
GeneralConversion of 16 bit to 8 bit or 24 bit Pin
harshi_mm211-Feb-08 22:25
memberharshi_mm211-Feb-08 22:25 
GeneralConversion from 8-bit to 32-bit Pin
Nilesh Kontamwar17-Jul-07 1:30
memberNilesh Kontamwar17-Jul-07 1:30 
GeneralRe: Conversion from 8-bit to 32-bit Pin
Nilesh Kontamwar22-Jul-07 18:08
memberNilesh Kontamwar22-Jul-07 18:08 
Generalexception:-array index out of bounds Pin
Platinumhimani27-Nov-06 20:37
memberPlatinumhimani27-Nov-06 20:37 
GeneralRe: exception:-array index out of bounds Pin
Shanu K S29-Nov-06 17:18
memberShanu K S29-Nov-06 17:18 
GeneralMissing parts of the code... Pin
desi_nerd19-Aug-06 3:07
memberdesi_nerd19-Aug-06 3:07 
GeneralRe: Missing parts of the code... [modified] Pin
npkinh19-Feb-08 15:11
membernpkinh19-Feb-08 15:11 
GeneralHelp plz.........very urgent Pin
Ashwini Iyengar25-Mar-05 22:07
memberAshwini Iyengar25-Mar-05 22:07 
GeneralErm... Pin
Christian Graus3-Mar-05 13:41
memberChristian Graus3-Mar-05 13:41 
GeneralRe: Erm... Pin
Teashirt219-Oct-07 9:50
memberTeashirt219-Oct-07 9:50 
GeneralCreating Image Pin
seasons1593-Mar-05 12:35
memberseasons1593-Mar-05 12:35 
Generalnon-aligned DWORD image width Pin
THollande28-Jul-04 23:15
memberTHollande28-Jul-04 23:15 
GeneralRe: non-aligned DWORD image width Pin
npkinh19-Feb-08 15:25
membernpkinh19-Feb-08 15:25 
Generalsample screen shot Pin
RabidCow21-May-04 12:18
memberRabidCow21-May-04 12:18 
GeneralRe: sample screen shot Pin
ShanuKS23-May-04 18:43
memberShanuKS23-May-04 18:43 
GeneralCQuantizer Pin
Kochise21-May-04 4:05
memberKochise21-May-04 4:05 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160525.2 | Last Updated 21 May 2004
Article Copyright 2004 by Shanu K S
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid