WMF / EMF File Format conversion C#
Asked Answered
O

2

5

In my program, I have a requirement to "playback" or "parse" windows metafiles (WMF and EMF). I have dug through MSDN and Google, and the closest I have come is the Graphics. EnumerateMetafile method. I can get it to work, in that my EnumerateMetafileProc callback is called, and I can then call PlayRecord. What is missing, is how to get usefull data out of that callback.

Example I looked at: http://msdn.microsoft.com/en-us/library/ms142060.aspx

The callback has a recordType parameter, which is an ENUM. Well this looks useful, except their seems to be no way to cast the data into any useful type.

My goal is to play back the creation of the WMF/EMF, so that I can make function calls to a specialized graphics class which has methods like (DrawLine, DrawPoint, DrawArc). In a sense, I am re-creating the WMF/EMF drawing in a completely different format (Converting).

Any help in this is extremely appreciated.

Ossicle answered 19/11, 2009 at 13:51 Comment(1)
may i ask what your destination format is? (If it's PDF you should really check into using a PDF printer driver)Blinny
V
10

Graphics.EnumerateMetafile, is unfortunately a very, very thin layer around the Win32 APIs. For each record in the EMF, you get an unmanaged memory address for the record-specific struct. No documentation about what it might contain - but then, there isn't much to go on in the Win32 world either.

So you need to consult the ancient texts!

This book came with a code sample CD-ROM that includes sample programs to use the EMF playback API.

This leaves you with two problems.

  1. The book is apparently out of print, so make sure that any used copy you buy includes a working CD-ROM.

  2. The sample code is all in C/C++ and it will be a non-trivial task to declare the necessary interop for the 100 or so structures that are used to describe all the EMF records.

So another approach might be to declare a huge interface in .NET that has a method for every GDI call you need to intercept, and then use C++/CLI to adapt the example C++ code so it calls onto your huge interface for each record.

Update

Although the MSDN documentation for EMF playback doesn't include details of specific EMF records, Microsoft has separately published the complete specification as of 2006:

MS-EMF: Enhanced Metafile Format

Also the author of the book I linked to above has made the source code of the CDROM samples available to download:

Source code for Windows Graphics Programming

Vermilion answered 2/2, 2010 at 12:42 Comment(0)
A
3

Check out this library: http://wmf.codeplex.com/

Idea is to loop through WMF records and convert shapes, brushes, etc. to other format

WmfDocument wmf = new WmfDocument();
wmf.Load(path);

foreach (var record in wmf.Records)
{
  if (record is WmfCreateBrushIndirectRecord)
  {
    var brush = record as WmfCreateBrushIndirectRecord;
    Console.WriteLine("Color: " + brush.Color);
    Console.WriteLine("Style: " + brush.Style);
    Console.WriteLine("Hatch: " + brush.Hatch);
    //Do something with brush here...
  }
  else if (record is WmfRectangleRecord)
  {
    var rectangle = record as WmfRectangleRecord;
    //Do something with rectangle...
  }
  else if ... //Other shapes to be implemented
}
Alded answered 4/3, 2012 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.