代码之家  ›  专栏  ›  技术社区  ›  DonBoitnott

将图标转换为Png

  •  3
  • DonBoitnott  · 技术社区  · 8 年前

    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看起来很糟糕。

    表单的标题图标:

    enter image description here

    使用 Bitmap.FromHicon(new Icon(theForm.Icon, new Size(16, 16)).Handle) : (注:用于 theForm.Icon.ToBitmap() ,但现在出现错误)

    enter image description here

    我在另一篇文章中读到一条评论,其中一位用户表示,如果使用PNG来导出图标,那么返回图像将是糟糕的,“因为PNG具有不止一位的透明度”。如果这就是我遇到的问题,那么我能做什么?

    2 回复  |  直到 4 年前
        1
  •  3
  •   Reza Aghaei    8 年前

    你可以使用 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相同。

        2
  •  0
  •   Community THelper    7 年前

    尝试Bitmap.FromHicon(this.Icon.Handle),您可能会得到更好的结果。如果png有压缩,至少ToBitmap()似乎会呕吐: Displaying an icon in a picturebox , http://community.sharpdevelop.net/forums/t/21851.aspx