-
前言
-
本文描述如何使用C# 实现图像转图标。正常情况下我们会直接使用Icon类的Icon.FromHandle(image.GetHicon())方法进行图像转Icon图标,但是众所周知的是这个方法的缺点是转换的图标会模糊、与原图不一致。那么如何获取高清的图标呢?
-
我们可以使用自定义填写数据的方式实现,如下图蓝色区域为Icon文件的头部信息,通过查看图像的头部信息,我们只需要按位填入对应的数值并填入原图byte[]类型数据即可创建Icon图像。
-
-
头部数据对照:
- 预 留:(地址00-01)(设置0)
- 类 型:(地址02-03)(1=ICO)
- 图片数量:(地址04-05)(默认1)
- 图像宽高:(地址06-07)(图标大小16、32...)
- 颜色数量:(地址08)(如果>=8bpp 设置0 )
- 预 留:(地址09)(设置0)
- 颜色平面:(地址10-11)(默认1)
- 数据大小:(地址14-17)(图像数据长度)
- 数据偏移:(地址18-21)(设置22,即图像数据起始位)
-
两种转换方式效果比较:
- 如下图,左图为自定义实现转换,右图为直接使用Icon转换。
-
运行效果

-
代码
-
自定义方式
public void ConvertToIcon(string imagePath, string outputPath, byte size = 128) { using (Image srcImage = Image.FromFile(imagePath)) { // 创建内存流保存ICO数据 using (MemoryStream stream = new MemoryStream()) { // 写入时ICO文件头:输入小端序,低位在前; // 输出时大端序,高位在前。 // 1、保留字 stream.Write(new byte[] { 0, 0 }, 0, 2); // 2、类型(1=ICO) stream.Write(new byte[] { 1, 0 }, 0, 2); // 3、图像数量 stream.Write(new byte[] { 1, 0 }, 0, 2); // 4、数据偏移 int dataOffset = 6 + 16; using (Image newImg = new Bitmap(srcImage, new Size(size, size))) { //5、创建图像数据数组(byte[])、获取图像数据 byte[] imgData = null; using (MemoryStream imageStream = new MemoryStream()) { newImg.Save(imageStream, ImageFormat.Png); imgData = imageStream.ToArray(); } //6、 设置图标 宽、高 stream.Write(new byte[] { size, size }, 0, 2); //7、 设置颜色数(0=真彩色)、保留字 stream.Write(new byte[] { 0, 0 }, 0, 2); //8、 设置颜色平面 stream.Write(new byte[] { 1, 0 }, 0, 2); //9、 设置每像素位数 stream.Write(new byte[] { 32, 0 }, 0, 2); //10、设置图像数据大小 stream.Write(BitConverter.GetBytes(imgData.Length), 0, 4); //11、设置数据偏移 stream.Write(BitConverter.GetBytes(dataOffset), 0, 4); //12、写入图像数据 stream.Write(imgData, 0, imgData.Length); stream.Flush(); //保存图标 File.WriteAllBytes(outputPath, stream.ToArray()); } } } } -
-
Icon直转方式
public Icon ConvertToIcon(string source, string target, int size = 128) { using (Image sourceImage = Image.FromFile(source)) { using (Bitmap newImage = new Bitmap(sourceImage, size, size)) { using (FileStream stream = new FileStream(target, FileMode.Create)) { Icon icon = Icon.FromHandle(newImage.GetHicon()); icon.Save(stream); return icon; } } } } -
窗体UI
public partial class MainForm : Form { private string sourcePath = null; private Image sourceImage; private Image targetImage; public MainForm() { InitializeComponent(); } private void btn_SelectedImage_Click(object sender, EventArgs e) { OpenFileDialog openFile = new OpenFileDialog(); openFile.InitialDirectory = Application.StartupPath; openFile.Filter = "(图像文件)|*.png;*.jpg;*.jpeg;*.bmp"; if (openFile.ShowDialog() == DialogResult.OK) { sourcePath = openFile.FileName; sourceImage = Image.FromFile(sourcePath); picx_SourceImage.Image = sourceImage; } } private void btn_ConvertImage_Click(object sender, EventArgs e) { ConvertToIcon(sourcePath, "output1.ico", (byte)128); picx_TargetImage.Image = Image.FromFile("output1.ico"); ConvertToIcon(sourcePath, "output2.ico", 128); picx_TargetImage2.Image = Image.FromFile("output2.ico"); } } -
总结
- 本文描述了如何无损实现图像转icon。主要是直接使用Icon类进行图像转换图标会与原图又不一致。在网上查找了一些方法实现了Icon无损转换功能。方便后面实现图标转换,其实网上有蛮多的在线图标转换工具站,嫌麻烦的也可以直接在网上找,这里主要是顺便学习一下如何自己编程实现。 
-
最后
- 如果你觉得这篇文章对你有帮助,不妨点个赞再走呗!
- 如有其他疑问,欢迎评论区留言讨论!
- 也可以关注微信公众号 [编程笔记in] ,一起交流学习!
- 项目地址: gitee.com/incodenotes…