我正在制作一个WPF应用程序,其中Image
有来自ImageSource
对象的Icon
。
为了将它保存在磁盘上,我将它们转换为byte[]
,而ImageSource
的getter将byte[]
转换回ImageSource
。
问题,当这样做时,结果看起来很明显,只有少数几种颜色可以存活。
这是一个完整的WPF解决方案,让您自己看看它看起来多么可怕:
XAML
<Window x:Class="POCicon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:POCicon"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MyViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Source="{Binding WithConversion}" MaxHeight="32" MaxWidth="32" Stretch="Fill" ></Image>
<Image Grid.Column="1" Source="{Binding NoConversion}" MaxHeight="32" MaxWidth="32" Stretch="Fill" ></Image>
</Grid>
</Window>
C#ViewModel
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace POCicon
{
public class MyViewModel
{
private System.Drawing.Icon Icon;
public MyViewModel()
{
Icon= System.Drawing.Icon.ExtractAssociatedIcon("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
}
public ImageSource WithConversion
{
get
{
byte[] byteArray;
using (MemoryStream serializer = new MemoryStream())
{
Icon.Save(serializer);
byteArray = serializer.ToArray();
}
using (MemoryStream deserializer = new MemoryStream(byteArray))
{
BitmapImage image = new BitmapImage();
image.BeginInit();
// image.CreateOptions = BitmapCreateOptions.PreservePixelFormat; //totally useless unfortunately
image.StreamSource = deserializer;
image.EndInit();
return image;
}
}
}
public ImageSource NoConversion
{
get
{
var imgSource = Imaging.CreateBitmapSourceFromHIcon(Icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
return imgSource;
}
}
}
}
有没有办法解决这个方法,或者让所需的结果走另一条路?要求是它必须在某个时刻成为Icon
对象,并最终成为byte[]
。
非常感谢
而不是使用Icon.Save()
,使用Icon.ToBitmap()
从Icon创建一个System.Drawing.Bitmap
,并保存:
var icon = System.Drawing.Icon.ExtractAssociatedIcon(
@"C:\Program Files (x86)\JetBrains\dotPeek\v1.1\Bin\dotpeek32.exe");
var bitmap = icon.ToBitmap();
byte[] buffer;
using (var memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
buffer = memoryStream.ToArray();
}
或者,在转换为BitmapSource后创建byte[]
:
var icon = System.Drawing.Icon.ExtractAssociatedIcon(
@"C:\Program Files (x86)\JetBrains\dotPeek\v1.1\Bin\dotpeek32.exe");
var bitmapSource = Imaging.CreateBitmapSourceFromHIcon(
icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
byte[] buffer;
using (var memoryStream = new MemoryStream())
{
encoder.Save(memoryStream);
buffer = memoryStream.ToArray();
}