Click here to Skip to main content
15,886,963 members
Articles / Multimedia / GDI+
Tip/Trick

Fast and high quality Bitmap to icon converter

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
29 Jul 2013CPOL1 min read 30K   11   3
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

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Spain Spain
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDo you have the code for WIN32 API C++ Pin
Rod2806201827-Jun-18 21:48
Rod2806201827-Jun-18 21:48 
QuestionInstructions? Pin
S1Niz7el28-Mar-18 14:45
S1Niz7el28-Mar-18 14:45 
QuestionNo XP support Pin
xiaozhunamen20-Oct-14 17:15
xiaozhunamen20-Oct-14 17:15 

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.