C#Winform窗体美化(⼋、Icon)
⼋、Icon
之前 Winform 项⽬也有在 Icon 上遇到些问题(这⾥的 Icon 指的是 .ico 类型的⽂件),⽐如刚开始不知道怎么让⾃⼰的程序 Icon 和其他软件⼀样可以放⼤,还有放⼤之后在⾳量合成器中会出现⽐较奇葩的效果之类的问题,这⾥简单整理下,以后再有其他问题再补充。
1、C# 代码转换 Icon 格式
最开始写 Winform 程序的时候,程序图标都是从⽹上 down 的,因为那时候我下载了个精简版的ps cs3 ⾥⾯不能保存 ico ⽂件,后来我了个可以⽤ ps cs3 保存 ico ⽂件的插件,就可以保存 Ico 格式的⽂件了,最近突发奇想能不能⽤ C# 代码来转换 Icon 格式,这个例⼦在⽹上看过,有个⽹站可以将 Png 转换成 Ico,OK 既然有就可以试验⼀下。
⽹上最多的代码就是:
Bitmap iconBm = new Bitmap(oriImage, size);
Icon icon = Icon.FromHandle(iconBm.GetHicon());
//保存⽂件省略
这玩意⼉确实能⽣成 Ico 格式的⽂件,但是这真的是个坑,因为⽣成的 Ico 是这样的:
⽹上有这种困扰的⼈很多,⼤致看了下原因是颜⾊位数的问题,那肯定的,颜⾊少的也太多了……
作者的⽅法原理是:先将image编码为png;再将png原样包装成⼀个icon。在这要谢谢作者提供的⽅法,提供了新思路,完美解决问题。这⾥顺便⼀贴⽅法代码(Save ⽅法是我顺⼿补的……):
/// <summary>
/// 将 Image(PNG)保存到指定⽬录⽂件名的 Icon
/// </summary>
/// <param name="image"></param>
/// <param name="file"></param>
/// <returns></returns>
public static bool Save(Image image, string file)
{
if (image != null)
{
using (Icon icon = ConvertToIcon(image))
{
try
{
FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write);
icon.Save(fs);
fs.Flush();
fs.Close();
fs.Dispose();
return true;
}
catch { }
catch { }
}
}
return false;
}
/// <summary>
/// 转换Image为Icon
/// </summary>
/// <param name="image">要转换为图标的Image对象</param>
/// <param name="nullTonull">当image为null时是否返回null。false则抛空引⽤异常</param>
/// <exception cref="ArgumentNullException" />
public static Icon ConvertToIcon(Image image, bool nullTonull = false)
{
if (image == null)
{
if (nullTonull) { return null; }
throw new ArgumentNullException("image");
}
using (MemoryStream msImg = new MemoryStream()
, msIco = new MemoryStream())
{
image.Save(msImg, ImageFormat.Png);
using (var bin = new BinaryWriter(msIco))
{
icon图标库/
/写图标头部
bin.Write((short)0);          //0-1保留
bin.Write((short)1);          //2-3⽂件类型。1=图标, 2=光标
bin.Write((short)1);          //4-5图像数量(图标可以包含多个图像)
bin.Write((byte)image.Width);  //6图标宽度
bin.Write((byte)image.Height); //7图标⾼度
bin.Write((byte)0);            //8颜⾊数(若像素位深>=8,填0。这是显然的,达到8bpp的颜⾊数最少是256,byte不够表⽰)            bin.Write((byte)0);            //9保留。必须为0
bin.Write((short)0);          //10-11调⾊板
bin.Write((short)32);          //12-13位深
bin.Write((int)msImg.Length);  //14-17位图数据⼤⼩
bin.Write(22);                //18-21位图数据起始字节
//写图像数据
bin.Write(msImg.ToArray());
bin.Flush();
bin.Seek(0, SeekOrigin.Begin);
return new Icon(msIco);
}
}
}
这个⽅法所转换的 Icon 是⽆损带透明的完美效果。
注:这⾥补充个⼩代码,是 OpenFileDialog 选择⽂件的:
OpenFileDialog 中可以设置 Filter 属性,默认不设置则可以选择所有⽂件,也可以限制只选⾃⼰需要的⽂件类型。
1. 限制⼀种⽂件类型:Filter=”照⽚|*.jpg”;
2. 限制同类多种⽂件类型:Filter=”照⽚|*.jpg;*jpeg;*png”;
3. 限制多种分类⽂件类型:Filter=”照⽚|.jpg;*jpeg;*png|⾳频|.mp3”;
代码如下:
//弹出打开图⽚对话框
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = "图⽚⽂件|*.jpg;*.jpeg;*.png";
if (fileDialog.ShowDialog() == DialogResult.OK)
{
//选择图⽚进⾏加载
oriImagePath = fileDialog.FileName;
}
2、可放⼤的程序图标
⽤过 win7 的⼩伙伴⼤部分应该都知道的,按住 ctrl 键 + ⿏标滚轮 可以对程序图标放⼤缩⼩,但是固定尺⼨的程序图标就不会跟着放⼤缩⼩,如图:
这种问题其实倒还是简单,因为 Icon ⽂件中可以放不同分辨率的图像,只需要在⽂件中创建⾼分辨率的版本就可以了:
创建多个分辨率的 Icon 之后,就不怕缩放问题了:
3、⾳量合成器的 Icon
沉积在可以放⼤图标的喜悦中之后,在给程序加声⾳的⼯作中,突然发现了个奇葩的东西:
我去~这是个什么⿁,在⽹上没查到是什么原因,我真是不知道怎么来描述这个问题……不过可以肯定是出在⼤分辨率的 Icon 上,既然这样,就再增加⼩分辨率的 Icon 进去。
实验发现,增加48*48⼤⼩的 Icon 就可以恢复正常了,如图:
4、IcoFX
IcoFX 确实是款不错的 Ico ⽂件编辑⼯具,上⾯的例⼦我也是⽤了这个软件编辑的 Ico,相⽐ visual studio 中的图像编辑器,IcoFX 操作更⽅便些,感兴趣的同学可以下载学习⼀下,软件有试⽤期,但是毕竟有注册机之类的神器啊,百度⼀下就可以了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。