Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Fast and high quality Bitmap to icon converter

0.00/5 (No votes)
29 Jul 2013 1  
When no XP support is necessary. Better Icon structure arrises and easy conversion is allowed.

Introduction 

A new fast and high quality Bitmap to Icon converter routine is provided to allow better look of icons under modern windows operating systems.  

Background 

To convert a Bitmap to an Icon is not an easy task. The different solutions under .NET provides poor Icon structures with bad look presentation. (This is more evident when scaling is necessary). If no XP compatibility is necesarry, a better and fast aproach is available.

Using the code 

A simple c# routine transform any Image to an Icon of desired size. The trick consists in packetized a PNG into an PNG  Icon structure. 

Windows internally has a better use of PNG Icons but this trick no works in XP systems. 

A pngiconheader structure before a normal PNG makes all work.  It consists in a simple header with Icon size, PNG size and a pngiconheader size. This pngiconheader derives from:

  1. An ICONDIR structure type 1. (code: 0,0,1,0,1,0)  
  2. One ICONDIRENTRY  Ico Format. (With Icon size, PNG size and PNG offset in memory structure). 

Windows detects automatically a PNG bitmap header, So no needs for extra work. Only 3 parameters to update from a PNG icon to another in the PNGIconHeader

public static class HelperIcon
{
    private static byte[] pngiconheader = 
                 new byte[]{0,0,1,0,1,0,0,0,0,0,1,0,24,0,0,0,0,0,0,0,0,0};
    public static Icon PngIconFromImage(Image img,int size=16)
    {
        using (Bitmap bmp = new Bitmap(img, new Size(size, size)))
        {
            byte[] png;
            using (System.IO.MemoryStream fs = new System.IO.MemoryStream())
            {
                bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
                fs.Position = 0;
                png=fs.ToArray();
            }
            
            using (System.IO.MemoryStream fs = new System.IO.MemoryStream())
            {
                if (size >= 256) size = 0;
                pngiconheader[6] = (byte)size;
                pngiconheader[7] = (byte)size;
                pngiconheader[14]=(byte)(png.Length & 255);
                pngiconheader[15] = (byte)(png.Length / 256);
                pngiconheader[18] = (byte)(pngiconheader.Length);

                fs.Write(pngiconheader, 0, pngiconheader.Length);
                fs.Write(png, 0, png.Length);
                fs.Position = 0;
                return new Icon(fs);
            }
        }
    }
}

Points of Interest

Creating a big PNG Icon and allow OS to scale it is now an option with good look results. Tray icons with animated shapes are now more easy to program, only a call from a created bitmap to inyect as PNG icon to tray.

History 

First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here