我正在使用以下代码(基于我在另一个答案中找到的内容)将图像(通常是添加到项目资源中的PNG)转换为图标,以用于表单标题等。
public static Icon IconFromImage(Image img)
{
using (var bmp = new Bitmap(img))
{
Byte[] ba;
using (var ms = new MemoryStream())
{
bmp.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
ba = ms.ToArray();
}
using (var imgData = new MemoryStream())
using (var writer = new BinaryWriter(imgData))
{
if (writer != null)
{
//Header (6 bytes)
writer.Write((Byte)0); // 0 reserved: set to 0
writer.Write((Byte)0); // 1 reserved: set to 0
writer.Write((Int16)1); // 2-3 image type: 1 = icon, 2 = cursor
writer.Write((Int16)1); // 4-5 number of images
//Image entry #1 (16 bytes)
writer.Write((Byte)bmp.Width); // 0 image width
writer.Write((Byte)bmp.Height); // 1 image height
writer.Write((Byte)0); // 2 number of colors
writer.Write((Byte)0); // 3 reserved
writer.Write((Int16)0); // 4-5 color planes
writer.Write((Int16)32); // 6-7 bits per pixel
writer.Write(ba.Length); // 8-11 size of image data
writer.Write(6 + 16); // 12-15 offset to image data
//Write image data
writer.Write(ba); // PNG data must contain the whole PNG data file!
writer.Flush();
writer.Seek(0, SeekOrigin.Begin);
return new Icon(imgData,16,16);
}
}
}
return null;
}
[从图像到图标,效果很好。但是在某些情况下,我需要获取该表单的标题图标并从中获取图像。当我使用实际的基于文件的ICO文件作为标题图像时,这种方法可以正常工作,但是现在我使用转换代码来获取表单的图标,因此生成的PNG看起来很恐怖。
表单标题图标:
使用Bitmap.FromHicon(new Icon(theForm.Icon, new Size(16, 16)).Handle)
渲染的图像:(注意:以前使用theForm.Icon.ToBitmap()
,但现在会出错)
[我在另一篇文章中读到一篇评论,其中用户说如果使用PNG派生图标,那么返回图像将是不好的,因为“ PNG具有不止一个透明度”。如果这是我遇到的问题,那么该怎么办?
您可以使用IconBitmapDecoder
获取保留像素格式的图标流,而使用PngBitmapEncoder
将该流保存在png图像中:
using System.Drawing;
using System.Windows.Media.Imaging;
class IconHelper
{
public static Bitmap PngFromIcon(Icon icon)
{
Bitmap png = null;
using (var iconStream = new System.IO.MemoryStream())
{
icon.Save(iconStream);
var decoder = new IconBitmapDecoder(iconStream,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.None);
using (var pngSteam = new System.IO.MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(decoder.Frames[0]);
encoder.Save(pngSteam);
png = (Bitmap)Bitmap.FromStream(pngSteam);
}
}
return png;
}
}
要使用这些类,您需要添加对PresentationCore
,WindowsBase
和System.Xaml
的引用。那么用法将是:
this.pictureBox1.Image = IconHelper.PngFromIcon(this.Icon);
并且结果与您用来创建图标的原始png相同。
尝试Bitmap.FromHicon(this.Icon.Handle),您可能会获得更好的结果。如果png有压缩,至少ToBitmap()似乎会阻塞:Displaying an icon in a picturebox,http://community.sharpdevelop.net/forums/t/21851.aspx