EMF+ support on Windows

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

EMF+ support on Windows

Post by tsdineen »

My company is starting to create EMF+ files, and I've found the latest ImageMagick Display for Windows doesn't view this format. I am using the ImageMagick-6.7.3-10-Q16-windows-dll.exe download to test this format. I have two files

ftp://ftp.sas.com/outgoing/ImageMagick/EMF.emf - standard emf file and is viewable
ftp://ftp.sas.com/outgoing/ImageMagick/EMFplus.emf - same picture in EMF+ format

If these files aren't there, it sometimes takes up to 30 minutes for them to post to the external site.

Thanks,
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

We use the standard PlayEnhMetaFile() Windows API method to render a EMF to a DIB. Apparently this does not work for EMF+ files. We'll need help from the Windows user community on how to render EMF+ files. We canvased Google and could not find a solution. You'll find the EMF coders in the source distribution as ImageMagick-6.7.4/coders/emf.c.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

Hopefully, this will help.

http://msdn.microsoft.com/en-us/library/ms533798.aspx

It looks like you have to use the GDI+ api, to determine these new formats. I haven't spent much time in this, so I don't know exactly what needs to be changed.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

Here is another link from our developer.

http://msdn.microsoft.com/en-us/library/ms536391.aspx

Among other things, it discusses the following:

Windows GDI+ provides the Metafile class so that you can record and display metafiles. A metafile, also called a vector image, is an image that is stored as a sequence of drawing commands and settings. The commands and settings recorded in a Metafile object can be stored in memory or saved to a file or stream.

GDI+ can display metafiles that have been stored in the following formats:
•Windows Metafile Format (WMF)
•Enhanced Metafile (EMF)
•EMF+

GDI+ can record metafiles in the EMF and EMF+ formats, but not in the WMF format.

EMF+ is an extension to EMF that allows GDI+ records to be stored. There are two variations on the EMF+ format: EMF+ Only and EMF+ Dual. EMF+ Only metafiles contain only GDI+ records. Such metafiles can be displayed by GDI+ but not by Windows Graphics Device Interface (GDI). EMF+ Dual metafiles contain GDI+ and GDI records. Each GDI+ record in an EMF+ Dual metafile is paired with an alternate GDI record. Such metafiles can be displayed by GDI+ or by GDI.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

We previously reviewed the pages you recommended. However, we are primarily Linux developers and know little about GDI and GDI+. The current implementation creates a DIB and writes to it with PlayEnhMetaFile(). We can then read the pixels from the DIB. There must be something equally easy to do for EMF+ and GDI+ but we could not find any reference code (the web pages shows how to write to a GDI+ but not how to convert it from EMF to GDI+ to pixels). Can your developer code up a small reference applications that reads an EMF and creates a buffer of RGBA pixels? If so we'll include it in a future release of ImageMagick.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

I looked at the spec a little last night, and isn't it as simple as

Code: Select all

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

INT main( )
{
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );

   Bitmap* image = new Bitmap( L"u:\\data\\emf\\EMFPlus.emf" );
   unsigned int wMax = image->GetWidth( );
   unsigned int hMax = image->GetHeight( );
   printf( "The width of the image is %u.\n", wMax );
   printf( "The height of the image is %u.\n", hMax ); 

   for ( unsigned int h = 0; h < hMax; h++ )
   {
      for ( unsigned int w = 0; w < wMax; w++ )
      {
         Color pixelColor;
         image->GetPixel( w, h, &pixelColor );
		 printf( "Pixel (%u, %u) is color %u.\n", w, h, pixelColor.GetValue( ) );  // ARGB value
      }
   }

   delete image;
   GdiplusShutdown( gdiplusToken );
   return 0;
}
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

Its never simple under Windows. We added
  • #include <windows.h>
    #include <gdiplus.h>
    using namespace Gdiplus;
To coders/emf.c and we get these errors (VisualStudio 2010):
  • 1>------ Build started: Project: IM_MOD_emf, Configuration: Release x64 ------
    1> emf.c
    1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplus.h(31): error C2061: syntax error : identifier 'Gdiplus'
    1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplus.h(31): error C2059: syntax error : ';'
    1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplus.h(32): error C2449: found '{' at file scope (missing function header?)
    1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplus.h(77): error C2059: syntax error : '}'
    1> MagickCore lib DLL import interface
    1> MagickCore module DLL export interface
    1>..\..\coders\emf.c(478): error C2065: 'GdiplusStartupInput' : undeclared identifier
    1>..\..\coders\emf.c(478): error C2146: syntax error : missing ';' before identifier 'gdiplusStartupInput'
    1>..\..\coders\emf.c(478): error C2065: 'gdiplusStartupInput' : undeclared identifier
    1>..\..\coders\emf.c(479): error C2275: 'ULONG_PTR' : illegal use of this type as an expression
    1> C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\basetsd.h(130) : see declaration of 'ULONG_PTR'
    1>..\..\coders\emf.c(479): error C2146: syntax error : missing ';' before identifier 'gdiplusToken'
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

I was using VS 2005. The only thing I did in my project was created a blank 32bit console app and added the gdiplus.lib for the link step. Probably some of the built-ins take care of locating the headers.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

The gdiplus.h header requires a C++ compiler. The coders are written in C.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

You can add /Tp to the project compiler options to make this file compile as c++. Within MSVS, right click on the source and select properties. In the C/C++ options go to Advanced. For "Compile As", select Comile as C++ Code (/TP). This works in VS2010, but not in my VS2005, even though the option is there.

Also, you will need to add gdiplus.lib to the additional list of libraries.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

There is now a namespace conflict. Both GDIPlus and ImageMagick define an Image class / structure:
  • 1>..\..\coders\emf.c(437): error C2872: 'Image' : ambiguous symbol
    1> could be 'C:\Users\******\ImageMagick-6.7.4\magick/magick-type.h(180) : _Image Image'
    1> or 'c:\program files (x86)\microsoft sdks\windows\v7.0a\include\GdiplusHeaders.h(372) : Gdiplus::Image'
Its not efficient, but could you write a small program that accepts an input and output filename and includes a Visual 2005 workspace to build it and release it under the ImageMagick license. The program would use GDI+ to read the file and write the RGBA bytes to the output file as raw bytes or words. We suspect the program would be 40-50 lines. We would then include this program in the ImageMagick distribution and call it as a delegate program whenever ImageMagick finds a EMF+ image file.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

Sorry, it took awhile to get back to the delegates app. I was able to build a tool that took an emf+ file in and ARGB out. I need to do some cleaning up, and it should be good to do.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

Ok, I have my delegate tool ready.

SYNTAX: emfplus [-format <value>][-debug] <infile> <outfile>
-format : list of images to convert to. Defaults RAW. Valid values are bmp,gif,jpg,png,tif
-debug : adds printout information.

The correct syntax for ImageMagick would be to just call it with an infile and outfile.

Here is the location for the project. It may take 30 minutes for the system to update.

ftp://ftp.sas.com/outgoing/ImageMagick/emfplus.cpp
ftp://ftp.sas.com/outgoing/ImageMagick/emfplus.sln
ftp://ftp.sas.com/outgoing/ImageMagick/emfplus.vcproj
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: EMF+ support on Windows

Post by magick »

Thanks, we'll try to get EMFPlus support in ImageMagick within the next few days.
tsdineen
Posts: 81
Joined: 2007-01-18T08:45:31-07:00

Re: EMF+ support on Windows

Post by tsdineen »

I've installed ImageMagick-6.7.5-Q16 32-bit, and I see the emfplus.exe in the C:\Program Files\ImageMagick-6.7.5-Q16. But IMDisplay still comes up blank. if I execute

U:\tmp\TESTHELPS\TH088480>sdswhence emfplus
C:\Program Files\ImageMagick-6.7.5-Q16\emfplus.EXE

U:\tmp\TESTHELPS\TH088480>emfplus -format bmp .\EMFPlus.emf .\EMFPlus.bmp

The bmp file views fine. It appears the delegate code is still pushing the emf format to the old delegate, and not the emfplus. This input file is the original file I submitted for this thread.

BTW: There is a third format for EMF. It is what we call 'dual'. It looks like the legacy, but has the emf+ in it as well. Many of those types do work in the old delegate tool, but some won't as they have true emf+ features.
Post Reply