Can't set palette in bitmap

16,774

Solution 1

This had me confused too. It seems bitmap.Palette returns a clone of the bitmap's palette. Once you've modified your copy, you need to reset the bitmap's pallete by using bitmap.Palette = palette, e.g.

ColorPalette palette = bitmap.Palette;
palette.Entries[i] = new Color(...);
....
bitmap.Palette = palette; // The crucial statement

See http://www.charlespetzold.com/pwcs/PaletteChange.html

Solution 2

According to Microsoft Reference Source, Palette property of Image class in .net, internally uses GDI+ Flat APIs for handling palettes. GdipGetImagePalette used for initializing ColorPalette object in get method and GdipSetImagePalette used for writing ColorPalette object data back to device is set method.

Each time in your for loop the line bmp.Palette.Entries.SetValue(b, i); forces the Image to call GdipGetImagePalette and data of bmp.Palette reinitialized and therefore you can see no change has been made to bmp.Palette after the loop.

To solve this problem you must do the following:

  1. Assign new alias to bmp.Palette by assigning it to a variable,
  2. Modify it by new alias (this prevents reloading),
  3. And put it back to the bmp.Palette.

Code:

var newAliasForPalette = bmp.Palette; // Palette loaded from graphic device
for (int i = 0; i < 256; i++)
{
    newAliasForPalette.Entries[i] = myColor[i];
}
bmp.Palette = newAliasForPalette; // Palette data wrote back to the graphic device

In my opinion, replacement of definition of Palette as a property with GetPalette() and SetPalette() methods by Microsoft, will be a great help in avoiding confusion.

Share:
16,774

Related videos on Youtube

user646265
Author by

user646265

I am a student in the UK who has an interest in computing. I drift in and out of programming and tend to use C#, which I'm learning more of and (hopefully) I'm becoming more competent in. I've also played about with C, C++, Pascal, VB and Assember (x86) and on the web I write HTML, CSS and JavaScript. My interests also include computing history, more importantly software history. I don't profess to be brilliant at programming, and for now I'll be asking more questions than I am answering, but I think I'm getting better!

Updated on March 07, 2022

Comments

  • user646265
    user646265 about 2 years

    I have been writing a PCX decoder and, so far, the PCX image itself parses fine, but I can't work out how to set the palette of a bitmap.

    I have created a bitmap like so:

    Bitmap bmp = new Bitmap(width,
                            height,
                            stride2,
                            System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
                            pixels);
    

    But I can't seem to set the palette using the following method:

    for (int i = 0; i < 256; i += 3)
    {
        Color b = new Color();
        b = Color.FromArgb(palette[i], palette[i + 1], palette[i + 2]);
        bmp.Palette.Entries.SetValue(b, i);
    }
    

    In this example, I have read through each byte in the palette of the pcx file and stored them in palette[]. from there, I have used this to set the entries in the palette of the bitmap. How do I set the colours?

  • Pedro77
    Pedro77 over 10 years
    Yeah, I think you are right, it returns a clone, it is the only explanation I know.