C# 图片无损转ICO(整理)

  • 概述

感觉网上文章整理的不全,我这边做个专栏,专门做这个事情吧,节省大家搜索、筛选、整理的时间精力。有用可以点个赞。转载请注明出处,谢谢。

 

  • 代码

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;   
 
public class ICON
{
        /// <summary>
        /// 保存为ICO文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <returns>true:成功 false:失败</returns>
        public static bool SaveAsICON(string filePath, int width = 0, int height = 0)
        {
            try
            {
                //基于源文件路径,仅修改后缀名为ico
                string fileDirectory = Path.GetDirectoryName(filePath);
                string fileSavePath = Path.Combine(fileDirectory, Path.GetFileNameWithoutExtension(filePath)) + ".ico";
 
                using (Bitmap bm = new Bitmap(filePath))
                {
                    //尺寸范围:【1-255,1-255】
                    width = width == 0 ? bm.Width : width;
                    width = width > 255 ? 255 : width;
 
                    height = height == 0 ? bm.Height : height;
                    height = height > 255 ? 255 : height;
 
                    //转换结果
                    bool isSuccess = ConvertImageToIcon(filePath, fileSavePath, new Size(width, height));
                    if (!isSuccess)
                    {
                        return isSuccess;
                    }
                    //转换成功,打开文本保存所在目录
                    Process.Start("explorer.exe", fileDirectory);
                    return isSuccess;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("转化失败。错误信息:" + ex.Message);
                return false;
            }
        }
 
        /// <summary>
        /// 图片转换为ico文件
        /// </summary>
        /// <param name="origin">原图片路径</param>
        /// <param name="destination">输出ico文件路径</param>
        /// <param name="iconSize">输出ico图标尺寸,不可大于255x255</param>
        /// <returns>是否转换成功</returns>
        private static bool ConvertImageToIcon(string origin, string destination, Size iconSize)
        {
            if (iconSize.Width > 255 || iconSize.Height > 255)
            {
                return false;
            }
 
            Bitmap originBMP = new Bitmap(origin);
            Image image = new Bitmap(originBMP, iconSize); //先读取已有的图片为bitmap,并缩放至设定大小
            MemoryStream bitMapStream = new MemoryStream(); //存原图的内存流
            MemoryStream iconStream = new MemoryStream(); //存图标的内存流
            image.Save(bitMapStream, ImageFormat.Png); //将原图读取为png格式并存入原图内存流,保证原图透明度、清晰度
            BinaryWriter iconWriter = new BinaryWriter(iconStream); 
 
            //下面是根据原图信息,进行文件头写入
            iconWriter.Write((short)0);//0-1保留
            iconWriter.Write((short)1);//2-3文件类型。1=图标, 2=光标
            iconWriter.Write((short)1);//4-5图像数量(图标可以包含多个图像)
            iconWriter.Write((byte)image.Width);//6图标宽度
            iconWriter.Write((byte)image.Height);//7图标高度
            iconWriter.Write((short)0);//8颜色数(若像素位深>=8,填0。这是显然的,达到8bpp的颜色数最少是256,byte不够表示) ;9保留。必须为0
            iconWriter.Write((short)0);//10-11调色板
            iconWriter.Write((short)32);//12-13位深
            iconWriter.Write((int)bitMapStream.Length);//14-17位图数据大小
            iconWriter.Write(22); //18 - 21位图数据起始字节
 
            //写入图像体至目标图标内存流
            iconWriter.Write(bitMapStream.ToArray());
            //保存流,并将流指针定位至头部以Icon对象进行读取输出为文件
            iconWriter.Flush();
            iconWriter.Seek(0, SeekOrigin.Begin);
            Stream iconFileStream = new FileStream(destination, FileMode.Create);
            Icon icon = new Icon(iconStream);
            icon.Save(iconFileStream); //储存图像
 
             //下面开始释放资源
            iconFileStream.Close();
            iconWriter.Close();
            iconStream.Close();
            bitMapStream.Close();
            originBMP.Dispose();
            icon.Dispose();
            image.Dispose();
            iconFileStream.Dispose();
 
            return File.Exists(destination);
        }
 
}

 

  • 引用

图标(ico,cur)文件的结构解析_ico文件格式解析-CSDN博客

【C#】无损转换Image为Icon - ahdung - 博客园 (cnblogs.com)

C#图片无损转换为ico格式_c# png转32位 ico-CSDN博客

 



posted @ 2024-03-25 13:55  tpen  阅读(184)  评论(0编辑  收藏  举报