+关注继续查看

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 128 ico 文件:

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

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

image.png

将PDF文件转换成PNG图片
有这样一个业务场景:需要在 WEB 页面中浏览 PDF 文件,PDF 文件存储在 FTP 服务器上,即 PDF 文件对外提供的访问地址的协议是 ftp 的。有如下几个硬条件、软需求的要求: - WEB 页面本身的可视区域不是很大; - 不想弹出对话框展示 PDF 文件; - 谷歌浏览器不支持在 http 协议的页面里内嵌 ftp 协议的路径; - 在 WEB 页面中使用系统默认的 PDF 阅读器的体验不是很好,滚动条啦,边框啦。
Qt&Vtk-003-读取jpg、png、dicom等格式图片
本文其实才能算是真正的Qt与Vtk结合,具体实现JPG、PNG、TIFF、DICOM、BMP及一个3D Cube显示。
C# 如何将PDF转为多种图像文件格式(Png/Bmp/Emf/Tiff)
PDF是一种在我们日常工作学习中最常用到的文档格式之一,但常常也会因为文档的不易编辑的特点,在遇到需要编辑PDF文档内容或者转换文件格式的情况时让人苦恼。通常对于开发者而言,可选择通过使用组件的方式来实现PDF文档的编辑或者格式转换,因此本文将介绍如何通过使用免费版的组件Free Spire.PDF for .NET来转换PDF文档。