I wrote some code to create ico files from any png, jpg, etc. images. The icons seem to be getting created correctly, and looks almost like the original image, when opened in Paint3d. Here is how it looks:
But when setting the image as a thumbnail to a folder, it looks weird and shiny.
Here is how it looks in windows file explorer:
Firstly, I would like to know if this is an issue in Windows itself, or is it code related? If this is Windows related, the code doesn't matter. If not, here it is:
I picked up a couple of code snippets from across the internet, so probably some non-optimized code, but here is the meat of my code:
//imagePaths => all images which I am converting to ico files
imagePaths.ForEach(imgPath => {
//create a temp png at this path after changing the original img to a squared img
var tempPNGpath = Path.Combine(icoDirPath, imgName.Replace(ext, ".png"));
var icoPath = tempPNGpath.Replace(".png", ".ico");
using (FileStream fs1 = File.OpenWrite(tempPNGpath)) {
Bitmap b = ((Bitmap)Image.FromFile(imgPath));
b = b.CopyToSquareCanvas(Color.Transparent);
b.Save(fs1, ImageFormat.Png);
fs1.Flush();
fs1.Close();
ConvertToIco(b, icoPath, 256);
}
File.Delete(tempPNGpath);
});
public static void ConvertToIco(Image img, string file, int size) {
Icon icon;
using (var msImg = new MemoryStream())
using (var msIco = new MemoryStream()) {
img.Save(msImg, ImageFormat.Png);
using (var bw = new BinaryWriter(msIco)) {
bw.Write((short)0); //0-1 reserved
bw.Write((short)1); //2-3 image type, 1 = icon, 2 = cursor
bw.Write((short)1); //4-5 number of images
bw.Write((byte)size); //6 image width
bw.Write((byte)size); //7 image height
bw.Write((byte)0); //8 number of colors
bw.Write((byte)0); //9 reserved
bw.Write((short)0); //10-11 color planes
bw.Write((short)32); //12-13 bits per pixel
bw.Write((int)msImg.Length); //14-17 size of image data
bw.Write(22); //18-21 offset of image data
bw.Write(msImg.ToArray()); // write image data
bw.Flush();
bw.Seek(0, SeekOrigin.Begin);
icon = new Icon(msIco);
}
}
using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
icon.Save(fs);
}
In the Extension class, the method goes:
public static Bitmap CopyToSquareCanvas(this Bitmap sourceBitmap, Color canvasBackground) {
int maxSide = sourceBitmap.Width > sourceBitmap.Height ? sourceBitmap.Width : sourceBitmap.Height;
Bitmap bitmapResult = new Bitmap(maxSide, maxSide, PixelFormat.Format32bppArgb);
using (Graphics graphicsResult = Graphics.FromImage(bitmapResult)) {
graphicsResult.Clear(canvasBackground);
int xOffset = (maxSide - sourceBitmap.Width) / 2;
int yOffset = (maxSide - sourceBitmap.Height) / 2;
graphicsResult.DrawImage(sourceBitmap, new Rectangle(xOffset, yOffset, sourceBitmap.Width, sourceBitmap.Height));
}
return bitmapResult;
}