【发布时间】:2017-02-18 20:57:48
【问题描述】:
我正在使用以下代码(基于我在另一个答案中找到的内容)将图像(通常是添加到项目资源中的 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 具有不止一点的透明度”。如果这是我遇到的问题,那我该怎么办?
【问题讨论】:
-
var img = this.Icon.ToBitmap()有什么问题? -
图标没有高质量的编码器。 Extract icon from file then save as .ico file with transparency 可能会回答你的问题
-
@RezaAghaei 通用版本似乎不喜欢 32bpp 规范。如果我将
writer.Write((Int16)32)更改为 24bpp,或者使用需要 16x16 大小的那个,那很好。我得到一个数组溢出异常。 -
@DonBoitnott 我用这个icon 作为我的
Form的Icon。然后使用this.pictureBox1.Image = this.Icon.ToBitmap();。质量完全可以接受。我错过了什么问题吗? -
@RezaAghaei 是的,我想你做到了。这与
ToBitmap()无关。它与获取 PNG 文件有关,将其放入我提供的代码中,然后尝试将内存中的 ICO 恢复为 PNG,而不会影响质量。
标签: c# .net image winforms gdi+