图片格式Png转Ico之System.Drawing与SixLabors.ImageSharp
System.Drawing 方式
/// <summary> /// 将Png格式图片转为Ico格式 /// </summary> /// <param name="imagePath">原图路径</param> /// <param name="outPath">Ico图片保存地址</param> /// <param name="size">图片转换目标尺寸</param> /// <param name="preserveAspectRatio">是否保持原来的纵横比</param> /// <returns></returns> public static bool ConvertPNGToIcon(string imagePath, string outPath, int size = 16, bool preserveAspectRatio = false) { System.Drawing.Image img = System.Drawing.Image.FromFile(imagePath); int width, height; if (preserveAspectRatio) { width = size; height = img.Height / img.Width * size; } else { width = height = size; } //调整大小 Bitmap bitmap = new Bitmap(width, height); using (Graphics graphics = Graphics.FromImage(bitmap)) { graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.DrawImage(img, 0, 0, width, height); } using (MemoryStream memoryStream = new MemoryStream()) { bitmap.Save(memoryStream, ImageFormat.Png);//将原图读取为png格式并存入原图内存流 return ConvertImageStreamIco(memoryStream, outPath, width, height); } }
SixLabors.ImageSharp方式
/// <summary> /// 将Png格式图片转为Ico格式 /// </summary> /// <param name="imagePath">原图路径</param> /// <param name="outPath">Ico图片保存地址</param> /// <param name="size">图片转换目标尺寸</param> /// <param name="preserveAspectRatio">是否保持原来的纵横比</param> /// <returns></returns> public static bool ConvertPNGToIconSIX(string imagePath, string outPath, int size = 16, bool preserveAspectRatio = false) { using (Image<Rgba32> image = SixLabors.ImageSharp.Image.Load<Rgba32>(imagePath)) { int width, height; //按原来的纵横比缩放到指定大小 if (preserveAspectRatio) { width = size; height = image.Height / image.Width * size; } else { width = height = size; } image.Mutate(x => x.Resize(width, height)); using (MemoryStream imageStream = new MemoryStream()) { image.SaveAsPng(imageStream);//将原图片以Png格式存在内存流中 imageStream.Position = 0;//将流的位置重置为开始 imageStream.Seek(0, SeekOrigin.Begin); return ConvertImageStreamIco(imageStream, outPath, width, height); } } }
公共部分
转ico
public static bool ConvertImageStreamIco(MemoryStream memoryStream, string outPath, int width, int height) { using (FileStream output = new FileStream(outPath, FileMode.OpenOrCreate)) { BinaryWriter iconWriter = new BinaryWriter(output); if (output != null && iconWriter != null) { //根据原图信息,进行文件头写入 // 0-1 reserved, 0 // 0-1保留 iconWriter.Write((byte)0); iconWriter.Write((byte)0); // 2-3 image type, 1 = icon, 2 = cursor //2-3文件类型。1 = 图标, 2 = 光标 iconWriter.Write((short)1); // 4-5 number of images //4-5图像数量(图标可以包含多个图像) iconWriter.Write((short)1); // image entry 1 // 0 image width //6图标宽度 iconWriter.Write((byte)width); // 1 image height //7图标高度 iconWriter.Write((byte)height); // 2 number of colors iconWriter.Write((byte)0); // 3 reserved iconWriter.Write((byte)0); // 4-5 color planes iconWriter.Write((short)0); // 6-7 bits per pixel iconWriter.Write((short)32); // 8-11 size of image data iconWriter.Write((int)memoryStream.Length); // 12-15 offset of image data iconWriter.Write((int)(6 + 16)); // write image data // png data must contain the whole png data file iconWriter.Write(memoryStream.ToArray()); //保存流,并将流指针定位至头部以Icon对象进行读取输出为文件 iconWriter.Flush(); return true; } } return false; }
或者
/// <summary> /// PNG转ICO /// </summary> /// <param name="memoryStream">源图片流</param> /// <param name="outPath">转出图片流</param> /// <returns></returns> private static bool ConvertImageStreamIco(MemoryStream memoryStream, string outPath) { using (FileStream output = new FileStream(outPath, FileMode.OpenOrCreate)) { BinaryWriter iconWriter = new BinaryWriter(output); if (output != null && iconWriter != null) { // png data must contain the whole png data file iconWriter.Write(memoryStream.ToArray()); //保存流,并将流指针定位至头部以Icon对象进行读取输出为文件 iconWriter.Flush(); return true; } } return false; }
第一种方式是在网上找的参考答案,目前不知iconWriter.Write()的其他值的作用