4

I'm trying to convert a Bitmap to an Icon and need to set the Bitmap's palette (See GetHicon from a 16 COLOR bitmap returns an image with less colors ) . For that, I'm trying to follow this answer: but I see that the palette is empty, and I can't create a new array because I have to change the original one. (I even tried it anyway. It doesn't work.)

I have:

ColorPalette palette = bitmap.Palette;
Color[] entries = palette.Entries;

But entries's length is Zero.

So how do I change the ColorPalette?

Community
  • 1
  • 1
ispiro
  • 26,556
  • 38
  • 136
  • 291
  • 1
    Why do you think the bitmap will have a palette? – Lee Taylor Dec 17 '12 at 19:20
  • 1
    @LeeTaylor Because of Hans Passant's comment in the first link, because of the second link, and because of [MSDN](http://msdn.microsoft.com/en-us/library/system.drawing.imaging.colorpalette%28v=vs.100%29.aspx). But do correct me if I'm wrong. How _is_ it done? – ispiro Dec 17 '12 at 19:27
  • 1
    A bitmap will only have a palette if it contains 256 colors or less. So, if you have a high-color image the pixel values map to the RGB color as opposed to a palette entry. – Lee Taylor Dec 17 '12 at 19:30
  • @LeeTaylor Thanks. You can change that into an answer. – ispiro Dec 17 '12 at 19:34
  • @LeeTaylor I'm loading the Bitmap from a file `using (Bitmap bitmap = new Bitmap(path))` - How would I make it a 16 Color bitmap? (The actual file has only 16 colors.) – ispiro Dec 17 '12 at 19:38

1 Answers1

5

As stated, a bitmap file won't necessarily have a palette. Indeed, modern color files with more than 256 colors are unlikely to (but still can (I think)) use a palette. Instead, the color information comes from the pixel values themselves (rather than pointing to a palette table)

I found the following code from ( http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/4a10d440-707f-48d7-865b-1d8804faf649/). I've not tested it (although the author states "tested in VS 2008 c# with .net 3.5").

It seems to handle the shrinking down the number of colors automatically...

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static bool DestroyIcon(IntPtr handle);

private void buttonConvert2Ico_Click(object sender, EventArgs e)
{
    OpenFileDialog openFileDialog1 = new OpenFileDialog

    openFileDialog1.InitialDirectory = "C:\\Data\\\" ;
    openFileDialog1.Filter = "BitMap(*.bmp)|*.bmp" ;
    openFileDialog1.FilterIndex = 2 ;
    openFileDialog1.RestoreDirectory = true ;

    if(openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        try
        {
            string sFn = openFileDialog1.FileName;
            MessageBox.Show("Filename=" + sFn);
            string destFileName = sFn.Substring(0, sFn.Length -3) +"ico";

            // Create a Bitmap object from an image file.
            Bitmap bmp = new Bitmap(sFn);
            // Get an Hicon for myBitmap. 
            IntPtr Hicon = bmp.GetHicon();
            // Create a new icon from the handle. 
            Icon newIcon = Icon.FromHandle(Hicon);
            //Write Icon to File Stream
            System.IO.FileStream fs = new System.IO.FileStream(destFileName, System.IO.FileMode.OpenOrCreate);
            newIcon.Save(fs);
            fs.Close();
            DestroyIcon(Hicon);
            setStatus("Created icon From=" + sFn + ", into " + destFileName);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: Could not read/write file. Original error: " + ex.Message);
        }
    }
}
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
  • I don't think it helps more than what I have, but you did provide the answer: There _is_ no palette. Thanks. – ispiro Dec 17 '12 at 20:02