我使用BitmapEncoder在WPF中创建各种格式的图像。例如,要从FrameworkElement创建png图像,我使用以下代码
BitmapEncoder imgEncoder = new PngBitmapEncoder();
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(32, 32, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(controlToConvert);
imgEncoder.Frames.Add(BitmapFrame.Create(renderBitmap));
我喜欢以相同的方式创建.ico文件。但我在WPF中找不到任何 IconBitmapEncoder 。还有其他办法吗?
此致
Jawahar
答案 0 :(得分:1)
没有。
我曾尝试将图像保存为* .ico,而其他.NET类并没有真正帮助(如果我没记错的话,它们只能解码,不能编码;但也许我只是做错了)。 * .ico可以是PNG图像的容器(虽然可能存在向后兼容性问题),因此您可以在其中添加完整的PNG,并使用正确的标题on wikipedia。
示例实施:
public static class PngToIcoConverter
{
public static byte[] Convert(byte[] data)
{
Image source;
using (var inStream = new MemoryStream(data))
{
source = Image.FromStream(inStream);
}
byte[] output;
using (var outStream = new MemoryStream())
{
// Header
{
// Reserved
outStream.WriteByte(0);
outStream.WriteByte(0);
// File format (ico)
outStream.WriteByte(1);
outStream.WriteByte(0);
// Image count (1)
outStream.WriteByte(1);
outStream.WriteByte(0);
}
// Image entry
{
// Width
outStream.WriteByte((byte)source.Width);
// Height
outStream.WriteByte((byte)source.Height);
// Number of colors (0 = No palette)
outStream.WriteByte(0);
// Reserved
outStream.WriteByte(0);
// Color plane (1)
outStream.WriteByte(1);
outStream.WriteByte(0);
// Bits per pixel
var bppAsLittle = IntToLittle2(Image.GetPixelFormatSize(source.PixelFormat));
outStream.Write(bppAsLittle, 0, 2);
// Size of data in bytes
var byteCountAsLittle = IntToLittle4(data.Length);
outStream.Write(byteCountAsLittle, 0, 4);
// Offset of data from beginning of file (data begins right here = 22)
outStream.WriteByte(22);
outStream.WriteByte(0);
outStream.WriteByte(0);
outStream.WriteByte(0);
// Data
outStream.Write(data, 0, data.Length);
}
output = outStream.ToArray();
}
return output;
}
private static byte[] IntToLittle2(int input)
{
byte[] b = new byte[2];
b[0] = (byte)input;
b[1] = (byte)(((uint)input >> 8) & 0xFF);
return b;
}
private static byte[] IntToLittle4(int input)
{
byte[] b = new byte[4];
b[0] = (byte)input;
b[1] = (byte)(((uint)input >> 8) & 0xFF);
b[2] = (byte)(((uint)input >> 16) & 0xFF);
b[3] = (byte)(((uint)input >> 24) & 0xFF);
return b;
}
}
答案 1 :(得分:1)
我知道问题已经得到解答,但最近我写了一篇关于Code Project的文章,我分享了IconBitmapEncoder的源代码。它在图标文件中编码BitmapImage,无需第三方dll或使用Win Forms。 100%Windows Presentation Foundation。
A High-Quality IconBitmapEncoder for WPF
我希望它对你有用。
答案 2 :(得分:0)
MSDN表示没有“IcoBitmapEncoder”。我建议您从Bitmap
获取BitmapFrame
,然后将其转换为图标,如下所示:
BitmapEncoder imgEncoder = new PngBitmapEncoder();
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(32, 32, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(comboBox1);
var frame = BitmapFrame.Create(renderBitmap);
Bitmap bitmap = GetBitmap(frame);
bitmap.SetResolution(72, 72);
System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(bitmap.GetHicon());
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate);
icon.Save(fs);
fs.Close();
您可以从here获取的方法GetBitmap
:
static Bitmap GetBitmap(BitmapSource source)
{
Bitmap bmp = new Bitmap(source.PixelWidth, source.PixelHeight,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
BitmapData data = bmp.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
return bmp;
}
答案 3 :(得分:0)
我使用这个扩展方法来创建一个 System.Drawing.Icon:
public static System.Drawing.Icon ToGDIIcon(this System.Windows.Media.ImageSource icon)
{
var image = (System.Windows.Media.Imaging.BitmapSource)icon;
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(image));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
using (var tempBitmap = new System.Drawing.Bitmap(ms))
{
return System.Drawing.Icon.FromHandle(tempBitmap.GetHicon());
}
}
}
...
var icon = imageSource.ToGDIIcon();