I am trying to create a high-quality icon (meaning: suitable for Win Vista / 7/8 ) from a PNG file programmatically in C # for use as shortcuts. Since the Bitmap.GetHIcon () function does not support such icons, and I want to avoid external dependencies or libraries, I am currently using the slightly modified ICO writer I found here in SO . I have working code, but I am having some problems displaying these icons on Windows. Relevant Code:
// ImageFile contains the path to PNG file public static String IcoFromImageFile(String ImageFile) { //... Image iconfile = Image.FromFile(ImageFile); //Returns a correctly resized Bitmap Bitmap bm = ResizeImage(256,256,iconfile); SaveAsIcon(bm, NewIconFile); return NewIconFile; } // From: https://stackoverflow.com/a/11448060/368354 public static void SaveAsIcon(Bitmap SourceBitmap, string FilePath) { FileStream FS = new FileStream(FilePath, FileMode.Create); // ICO header FS.WriteByte(0); FS.WriteByte(0); FS.WriteByte(1); FS.WriteByte(0); FS.WriteByte(1); FS.WriteByte(0); // Image size // Set to 0 for 256 px width/height FS.WriteByte(0); FS.WriteByte(0); // Palette FS.WriteByte(0); // Reserved FS.WriteByte(0); // Number of color planes FS.WriteByte(1); FS.WriteByte(0); // Bits per pixel FS.WriteByte(32); FS.WriteByte(0); // Data size, will be written after the data FS.WriteByte(0); FS.WriteByte(0); FS.WriteByte(0); FS.WriteByte(0); // Offset to image data, fixed at 22 FS.WriteByte(22); FS.WriteByte(0); FS.WriteByte(0); FS.WriteByte(0); // Writing actual data SourceBitmap.Save(FS, System.Drawing.Imaging.ImageFormat.Png); // Getting data length (file length minus header) long Len = FS.Length - 22; // Write it in the correct place FS.Seek(14, SeekOrigin.Begin); FS.WriteByte((byte)Len); FS.WriteByte((byte)(Len >> 8)); FS.Close(); }
This compiles and works, but with one problem. Windows does not display the icon on the shortcut correctly. I do this also programmatically, but it happens even if I do it manually (via File Properties, Change Icon). The problem is that the icon is cropped (the image itself is displayed correctly). It depends on the image, but usually only about 20% of the actual icon is displayed. If I open the file in an image viewer such as XNView, it will display completely and correctly, but MS Paint will not. I took this screenshot along with a correctly displayed icon for comparison

I suspect that the error lies in the method of saving ICOs, but even after comparing them with the usually displayed ICOs in the hex editor, the title is spelled correctly, but the part of the PNG image itself seems different. Anyone have an idea? I also welcome better, less hacker solutions.
Lennart
source share