【问题标题】:How to convert an image to an icon without losing transparency?如何在不丢失透明度的情况下将图像转换为图标?
【发布时间】:2014-01-27 17:21:58
【问题描述】:

我有 PNG 图像,需要在显示之前将其转换为图标。

我就是这样做的:

public Icon ImageToIcon(Image imgTest)
{
    Bitmap bitmap = new Bitmap(imgTest);
    Icon icoTest;

    IntPtr iPtr = bitmap.GetHicon();
    icoTest = (Icon) Icon.FromHandle(iPtr).Clone();

    return icoTest;
}

这样做后我失去了透明度,alpha 透明图像没有按预期呈现....这可以解决吗?

【问题讨论】:

标签: c# winforms alpha-transparency


【解决方案1】:

不,还有很多。图标有一个非常精细的内部结构,经过优化可以在 1980 年代的硬件上合理地工作。一个图标图像有三个位图,一个用于图标,一个单色位图指示图像的哪些部分是透明的,另一个单色位图指示哪些部分是反转的。生成这些单色位图非常痛苦,.NET 不支持它们。 Bitmap.GetHicon() 也没有尝试过。您需要一个库来为您完成这项工作。

Vista 松了一口气,它开始支持包含 PNG 图像的图标。您将有机会使用自己的代码生成它。像这样:

    public static Icon IconFromImage(Image img) {
        var ms = new System.IO.MemoryStream();
        var bw = new System.IO.BinaryWriter(ms);
        // Header
        bw.Write((short)0);   // 0 : reserved
        bw.Write((short)1);   // 2 : 1=ico, 2=cur
        bw.Write((short)1);   // 4 : number of images
        // Image directory
        var w = img.Width;
        if (w >= 256) w = 0;
        bw.Write((byte)w);    // 0 : width of image
        var h = img.Height;
        if (h >= 256) h = 0;
        bw.Write((byte)h);    // 1 : height of image
        bw.Write((byte)0);    // 2 : number of colors in palette
        bw.Write((byte)0);    // 3 : reserved
        bw.Write((short)0);   // 4 : number of color planes
        bw.Write((short)0);   // 6 : bits per pixel
        var sizeHere = ms.Position;
        bw.Write((int)0);     // 8 : image size
        var start = (int)ms.Position + 4;
        bw.Write(start);      // 12: offset of image data
        // Image data
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        var imageSize = (int)ms.Position - start;
        ms.Seek(sizeHere, System.IO.SeekOrigin.Begin);
        bw.Write(imageSize);
        ms.Seek(0, System.IO.SeekOrigin.Begin);

        // And load it
        return new Icon(ms);
    }

在 .NET 4.5 和 Windows 8.1 上测试。请注意您会在边缘透明的 PNG 图像上看到“边缘”的可能性。仅当图像以众所周知的背景颜色显示时才有效。根据设计,图标永远不能依赖它。专用的图标编辑器永远是获得好看图标的唯一真正好方法。

【讨论】:

  • 对于Cursor,将类型设置为 2 并写入热点 X 和 Y 坐标,而不是颜色平面计数和 BPP。
猜你喜欢
  • 2014-02-06
  • 1970-01-01
  • 2017-12-27
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 1970-01-01
相关资源
最近更新 更多