Как отобразить Метафайл Windows?

Мне нужно отобразить Метафайл Windows (EMF) используя WPF, как я могу это сделать?

Edit:

Я бы оставил изображение векторным.

2 ответов


посмотри 3-й партии библиотеки Ab2d.ReadWmf.

Обновление #1: Обзор

во-первых, этот пост заявляет, что Microsoft не намерена поддерживать файлы EMF в WPF. Это не значит, что этого нельзя сделать, просто они не поддержат их.

смотреть на!--15-->Википедия страницы о формате WMF / EMF я вижу, что он описывает EMF как:

по существу, файл WMF сохраняет список вызовов функций, которые должны быть выданы слою интерфейса графического устройства Windows (GDI) для отображения изображения на экране. Поскольку некоторые функции GDI принимают указатели на функции обратного вызова для обработки ошибок, файл WMF может ошибочно включать исполняемый код.

Если вы много работали с WPF, вы знаете, что WPF принципиально отличается от GDI. Краткий обзор доступен здесь. Это означает, что вам нужно будет прочитать в файле EMF и переведите вызовы GDI в вызовы WPF. вот нить где они обсуждают процесс. По-моему, много работы.

к счастью, Microsoft предоставляет интерфейс для чтения в Метафайлах Windows. Взгляните на этой теме для примера и документация здесь, но это приведет вас только к половине пути, так как это не визуальный WPF. На данный момент я думаю, что самым простым решением было бы создать элемент управления WinForms в вашем приложении WPF и разместите его внутри элемента управления WindowsFormsHost.

Обновление #2: Образец Кода

для отображения файла EMF в приложении WPF:

  1. создайте WinForms UserControl
  2. загрузите файл EMF в объект метафайла и нарисуйте его в обработчике OnPaint.
  3. добавить ссылку на библиотеку WindowsFormsIntegration
  4. разместить элемент управления WinForms внутри WindowsFormsHost элемент

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");
        }
    }

}

недостатком является то, что вам понадобится справочная система.Рисунок.dll (GDI+) в ваше приложение WPF, но это не должно быть большой проблемой.