C# 如何显示Windows图元文件?

C# 如何显示Windows图元文件?,c#,.net,wpf,.emf,metafile,C#,.net,Wpf,.emf,Metafile,我需要使用WPF显示(EMF),我该怎么做? 编辑: 我想保持图像矢量的基础。看一看图片 更新#1:概述 首先,声明微软不打算在WPF中支持EMF文件。这并不意味着不能做到,只是他们不会支持他们 查看有关WMF/EMF格式的信息,我发现它将EMF描述为: 基本上,WMF文件存储了一系列函数调用,这些调用必须发送到Windows图形设备接口(GDI)层才能在屏幕上显示图像。由于某些GDI函数接受指向回调函数的指针以进行错误处理,WMF文件可能会错误地包含可执行代码 如果您经常使用WPF,您就会知道

我需要使用WPF显示(EMF),我该怎么做?

编辑: 我想保持图像矢量的基础。

看一看图片

更新#1:概述

首先,声明微软不打算在WPF中支持EMF文件。这并不意味着不能做到,只是他们不会支持他们

查看有关WMF/EMF格式的信息,我发现它将EMF描述为:

基本上,WMF文件存储了一系列函数调用,这些调用必须发送到Windows图形设备接口(GDI)层才能在屏幕上显示图像。由于某些GDI函数接受指向回调函数的指针以进行错误处理,WMF文件可能会错误地包含可执行代码

如果您经常使用WPF,您就会知道WPF与GDI有着本质的不同。有一个快速概述。这意味着您需要读入EMF文件并将GDI调用转换为WPF调用。他们在那里讨论过程。对我来说,这听起来是一项艰巨的工作

幸运的是,Microsoft提供了一个用于读取Windows图元文件的界面。请看一个示例和,但由于它不是WPF可视化的,所以这只会让您走到一半。此时,我认为最简单的解决方案是在WPF应用程序中创建WinForms控件,并将其托管在WindowsFormsHost控件中

更新#2:代码示例

要在WPF应用程序中显示EMF文件,请执行以下操作:

  • 创建WinForms用户控件
  • 将EMF文件加载到元文件对象中,并在OnPaint处理程序中绘制它
  • 添加对WindowsFormsIntegration库的引用
  • 将WinForms控件宿主在WindowsFormsHost元素中
  • 用户控制:

    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:


    下面是一个实用函数,用于加载EMF文件并将其转换为WPF:

    您可以这样简单地使用它:

    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                // img is of Image type for example
                img.Source = Emfutilities.ToBitmapSource("SampleMetafile.emf");
            }
        }
    
    }
    

    缺点是您需要在WPF应用程序中引用System.Drawing.dll(GDI+),但这不是一个大问题。

    另请参见。请使用重要的示例或引用更新您的答案,通用链接没有用处。+1对于您的上次更新,您能展示如何创建表单解决方案来显示EMF吗?它可以+1。但EMF用于矢量图形,BitmapSource(如您所知)是光栅。如何修复此问题?您没有在问题中指定要基于图像向量。为此,您需要将EMF记录转换为纯XAML。这是一项艰巨的工作(可能也是CPU密集型工作),并不是免费的午餐:-)请参阅Dan Busha的转换工具答案。注意:您也可以使用nuget软件包:“System.Drawing.Common”if“System.Drawing.Imaging”在您的解决方案中不受支持。
    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");
            }
        }
    
    }