Click here to Skip to main content
Click here to Skip to main content

Image Bit depth conversion from 32 Bit to 8 Bit

, 20 May 2004
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)

About the Author

Shanu K S
Software Developer NeST
India India
No Biography provided

Comments and Discussions

 
Generalpixel data Pinmembersandeeprattu1-Jul-09 21:18 
Questionconvert 16 bit to 8 bit? Pinmemberharshi_mm214-Feb-08 0:34 
GeneralConversion of 16 bit to 8 bit or 24 bit Pinmemberharshi_mm211-Feb-08 22:25 
GeneralConversion from 8-bit to 32-bit PinmemberNilesh Kontamwar17-Jul-07 1:30 
GeneralRe: Conversion from 8-bit to 32-bit PinmemberNilesh Kontamwar22-Jul-07 18:08 
Generalexception:-array index out of bounds PinmemberPlatinumhimani27-Nov-06 20:37 
GeneralRe: exception:-array index out of bounds PinmemberShanu K S29-Nov-06 17:18 
GeneralMissing parts of the code... Pinmemberdesi_nerd19-Aug-06 3:07 
GeneralRe: Missing parts of the code... [modified] Pinmembernpkinh19-Feb-08 15:11 
GeneralHelp plz.........very urgent PinmemberAshwini Iyengar25-Mar-05 22:07 
GeneralErm... PinmemberChristian Graus3-Mar-05 13:41 
GeneralRe: Erm... PinmemberTeashirt219-Oct-07 9:50 
GeneralCreating Image Pinmemberseasons1593-Mar-05 12:35 
Generalnon-aligned DWORD image width PinmemberTHollande28-Jul-04 23:15 
GeneralRe: non-aligned DWORD image width Pinmembernpkinh19-Feb-08 15:25 
Generalsample screen shot PinmemberRabidCow21-May-04 12:18 
GeneralRe: sample screen shot PinmemberShanuKS23-May-04 18:43 
GeneralCQuantizer PinmemberKochise21-May-04 4:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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 | Mobile
Web02 | 2.8.140721.1 | Last Updated 21 May 2004
Article Copyright 2004 by Shanu K S
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid