ico
格式是我们常见的一种图标格式,曾经常常通过一些别的软件进行转换,现在研究了一下C#其实也可以进行转换。
网上很多方法是通过
Bitmap
直接获取句柄转为
Icon
对象并保存,这样得到的
ico
质量非常差。
左找右找发现可以直接
读取图像全部信息
,然后先
写入
ico
文件头
,再
填入图像信息
,即可实现
无损转换
。
1,
ico
图标文件结构
首先来看一下
ico
文件的结构:
根据这个,我们可以使用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 ? "是" : "否"));
可见这样,就实现了转换的功能:
有这样一个业务场景:需要在 WEB 页面中浏览 PDF 文件,PDF 文件存储在 FTP 服务器上,即 PDF 文件对外提供的访问地址的协议是 ftp 的。有如下几个硬条件、软需求的要求:
- WEB 页面本身的可视区域不是很大;
- 不想弹出对话框展示 PDF 文件;
- 谷歌浏览器不支持在 http 协议的页面里内嵌 ftp 协议的路径;
- 在 WEB 页面中使用系统默认的 PDF 阅读器的体验不是很好,滚动条啦,边框啦。
PDF是一种在我们日常工作学习中最常用到的文档格式之一,但常常也会因为文档的不易编辑的特点,在遇到需要编辑PDF文档内容或者转换文件格式的情况时让人苦恼。通常对于开发者而言,可选择通过使用组件的方式来实现PDF文档的编辑或者格式转换,因此本文将介绍如何通过使用免费版的组件Free Spire.PDF for .NET来转换PDF文档。