C#实现把图片转换为ico格式

简介: C#实现把图片转换为ico格式

ico格式是我们常见的一种图标格式,曾经常常通过一些别的软件进行转换,现在研究了一下C#其实也可以进行转换。

网上很多方法是通过Bitmap直接获取句柄转为Icon对象并保存,这样得到的ico质量非常差。

左找右找发现可以直接读取图像全部信息,然后先写入ico文件头,再填入图像信息,即可实现无损转换

1,ico图标文件结构

首先来看一下ico文件的结构:

ico文件结构解析.png

根据这个,我们可以使用C#中使用内存流和文件流将ico文件的头信息和图像体组装起来,实现格式转换。

2,代码实现

为了保证ico保留透明度且不失真,我们将图片读取为png格式数据,再将数据写入目标文件。这里我写了个函数来实现图片转换ico

/// <summary>
/// ICON图标文件头模板
/// </summary>
private static readonly byte[] ICON_HEAD_TEMPLATE = {
    0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
    0xC4, 0x6E, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00
};

/// <summary>
/// 图片转换为ico文件
/// </summary>
/// <param name="origin">原图片路径</param>
/// <param name="destination">输出ico文件路径</param>
/// <param name="iconSize">输出ico图标尺寸,不可大于255x255</param>
/// <returns>是否转换成功</returns>
public static bool ConvertImageToIcon(string origin, string destination, Size iconSize)
{
    if (iconSize.Width > 255 || iconSize.Height > 255)
    {
        return false;
    }
    // 把原图并缩放到指定大小
    Image originResized = new Bitmap(Image.FromFile(origin), iconSize);
    // 存放缩放后的原图的内存流
    MemoryStream originImageStream = new MemoryStream();
    // 将缩放后的原图以png格式写入到内存流
    originResized.Save(originImageStream, ImageFormat.Png);
    // Icon的文件字节内容
    List<byte> iconBytes = new List<byte>();
    // 先加载Icon文件头
    iconBytes.AddRange(ICON_HEAD_TEMPLATE);
    // 文件头的第7和8位分别是图标的宽高,修改为设定值,不可大于255
    iconBytes[6] = (byte)iconSize.Width;
    iconBytes[7] = (byte)iconSize.Height;
    // 文件头的第15到第18位是原图片内容部分大小
    byte[] size = BitConverter.GetBytes((int)originImageStream.Length);
    iconBytes[14] = size[0];
    iconBytes[15] = size[1];
    iconBytes[16] = size[2];
    iconBytes[17] = size[3];
    // 追加缩放后原图字节内容
    iconBytes.AddRange(originImageStream.ToArray());
    // 利用文件流保存为Icon文件
    Stream iconFileStream = new FileStream(destination, FileMode.Create);
    iconFileStream.Write(iconBytes.ToArray(), 0, iconBytes.Count);
    // 关闭所有流并释放内存
    iconFileStream.Close();
    originImageStream.Close();
    originResized.Dispose();
    return File.Exists(destination);
}

大家可以对照上面的ico格式解析图来看写入的文件头信息,以及修改了哪几个字节,就明白了。

调用函数即可实现转换,例如我这里转换输出一个128 x 128ico文件:

bool saved = ConvertImageToIcon(@"C:\Users\swsk33\Pictures\头像与图标\38.jpg", @"E:\中转\icon.ico", new Size(128, 128));
Console.WriteLine("是否转换成功:" + (saved ? "是" : "否"));

可见这样,就实现了转换的功能:

image.png

相关文章
|
3月前
|
存储 传感器 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C#)
55 0
|
3月前
|
存储 监控 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C#)
27 0
|
3月前
|
数据采集 API 开发工具
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C#)
15 0
|
1月前
|
API C# 数据安全/隐私保护
C# 实现网页内容保存为图片并生成压缩包
C# 实现网页内容保存为图片并生成压缩包
|
6月前
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
260 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
2月前
|
JSON C# 数据格式
C# 处理gzip格式的json
C# 处理gzip格式的json
19 0
|
3月前
|
存储 传感器 监控
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
32 0
|
3月前
|
C#
C# 获取文件编码格式
C# 获取文件编码格式
24 0
|
8月前
|
存储 传感器 算法
Baumer工业相机堡盟工业相机如何通过BGAPISDK显示Bayer彩色格式的图像(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK显示Bayer彩色格式的图像(C#)
78 0
|
4月前
|
XML 存储 JSON
C# | JSON格式与XML格式互相转换
JSON格式与XML格式是目前互联网上使用最为广泛的数据交换格式之一,而两种格式各自有着自己的特点和优势。 在实际开发中,我们经常需要将数据在不同的系统或模块之间进行传递和转换,而JSON格式和XML格式的互相转换是一项非常基础和必要的技能。 同时,对于需要将数据存储在不同的介质中的应用场景,比如在移动端本地存储数据,或者在服务器端将数据保存到文件或数据库中,也需要将JSON或XML格式进行相应的转换。 因此,熟练掌握JSON与XML格式互相转换的方法对于开发人员来说是非常重要的。在本文中,我们将介绍常用的JSON和XML互相转换的方法及其实现。
58 0
C# | JSON格式与XML格式互相转换