C#无损转换Image为Icon的方法
如题,市面上常见的方法是:
var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle); //通过句柄得到图标
此法的问题是,如果图像是透明背景,那么得到的Icon的边缘就是毛糙的,像是先垫了一层背景色然后再去色的效果,很不如人意,用过的朋友都知道。尚未研究是bmp.GetHicon出的问题,还是Icon.FromHandle有问题,日后有闲心再捣鼓下。
下面给出完美转换方法:
/// <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)) { //写图标头部 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); } } }
如码所示,方法的原理是:
1、先将image编码为png
2、再将png原样包装成一个icon
第1步虽然是重编码,但png是无损格式,图像质量不会有丝毫损失。然后在二进制层面原封不动的把转换得到的png塞入图标。所以整个方法担得起【无损】的说法,介意失真的朋友请放心使用。注意:方法中并未对原图size做检查、处理,所以请先确保原图的尺寸符合图标规格再传入;另外,不负责销毁原图,请调用者在外部负责。
下面是闲扯:
为了解决这个问题还真费了番功夫,stackoverflow、codeproject等神迹多现的地方逛了几圈都没找到如意的法子,思索一番后感觉可以从图标格式上尝试,然后在万能的msdn果然找到一篇讲icon格式的文档:https://msdn.microsoft.com/en-us/library/ms997538.aspx,还好不算很难理解,一番尝试之下,方法出炉。
-文毕-
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
相关文章
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25