请查看第三方库Ab2d.ReadWmf。
更新 #1: 概述
首先,这篇文章称微软不打算在WPF中支持EMF文件。这并不意味着无法完成,只是微软将不提供支持。
查看关于WMF / EMF格式的维基百科页面,我发现它将EMF描述为:
实质上,WMF文件存储了必须向Windows GDI(图形设备接口)层发出的函数调用列表,在屏幕上显示图像。由于某些GDI函数接受指向回调函数的指针以进行错误处理,因此WMF文件可能会错误地包含可执行代码。
如果您经常使用WPF,您就知道WPF与GDI根本不同。可以在此处获得快速概述:此处。这意味着您需要读取EMF文件并将GDI调用转换为WPF调用。这里讨论了该过程。对我来说,这听起来是很多工作。
幸运的是,微软提供了一个接口来读取Windows图元文件。请参阅此处的帖子以获取示例和此处的文档,但这只能让您完成一半,因为它不是WPF可视化对象。此时,我认为最简单的解决方案是在WPF应用程序中创建一个WinForms控件,并将其托管在WindowsFormsHost控件内部。
更新 #2:代码示例
要在WPF应用程序中显示EMF文件:
UserControl:
public partial class UserControl1 : UserControl
{
private Metafile metafile1;
public UserControl1()
{
InitializeComponent();
metafile1 = new Metafile(@"C:\logo2.emf");
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(metafile1, 0, 0);
}
}
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1"
Title="MainWindow" Height="200" Width="200">
<Grid>
<WindowsFormsHost>
<app:UserControl1/>
</WindowsFormsHost>
</Grid>
</Window>
这里有一个实用函数,可以加载 EMF 文件并将其转换为 WPF BitmapSource:
public static class Emfutilities
{
public static BitmapSource ToBitmapSource(string path)
{
using (System.Drawing.Imaging.Metafile emf = new System.Drawing.Imaging.Metafile(path))
using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(emf.Width, emf.Height))
{
bmp.SetResolution(emf.HorizontalResolution, emf.VerticalResolution);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
{
g.DrawImage(emf, 0, 0);
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
}
}
}
你可以像这样简单使用它:
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// img is of Image type for example
img.Source = Emfutilities.ToBitmapSource("SampleMetafile.emf");
}
}
}
缺点是你需要将 System.Drawing.dll(GDI+)引用到你的WPF应用程序中,但这不应该是一个大问题。