7

Is there a way to draw an emf metafile (exported form a drawing tool) with antialiasing enabled? The tools I tried are not capable of exporting emf files antaliased so I wondered if I can turn it back on manually when drawing the emf in the OnPaint override of my Controls.

If anyone can confirm that is technically possible to generate antialiased emf files, another solution would be to use a drawing tool that can export to antialiased emf or have a 3rd party converter do this later. If anyone knowns such a tool, please let me know.

EDIT: When looking at the emf instructions it doesn't seem that emf itself can actually store the information whether it is to be rendered antialiased or not. At least I couldn't find anything. It is more likely that the antialiasing is done by the playback engine. For example when I open an emf in Word 2007 it is rendered antialiased. But not when I draw it with GDI+ "playback engine" (Graphics.DrawImage(...)). or when I view it the standard windows image viewer. This makes me believe that some tools actually have their own emf playback engine. So maybe there is free .NET library (preferably with source code) that give me an object model of the emf instructions stored in the parsed emf file so I can play it back myself instead of using Graphics.DrawImage(...)?

bitbonk
  • 48,890
  • 37
  • 186
  • 278
  • 2
    If all else fails you can probably draw it at four times the size or so and then downsample. – Joey Nov 23 '09 at 13:30
  • I tried this, at small sizes this still looks ugly Also using this approach there is proably a ugly memory overhead. (I will be displaying lots of such UserControls at once). – bitbonk Nov 23 '09 at 17:33
  • Duplicate: http://stackoverflow.com/questions/1422949/emf-with-forced-antialiasing – liori Nov 23 '09 at 17:36
  • Small sizes will look ugly no matter what, because your points will be cast to integer pixel boundaries. You have to choose which style of ugly is most acceptable. – Mark Ransom Nov 23 '09 at 17:50
  • Don't forget to set InterpolationMode to HighQualityBicubic before downsampling. – Dan Byström Nov 23 '09 at 18:02
  • You can convert the EMF file at runtime to an EMF+ Metafile. [Here's C# how to do it](http://stackoverflow.com/a/38037992/58391). – codekaizen Jun 27 '16 at 21:30

3 Answers3

9

We had a similar issue in a DirectX project. Upscaling and downscaling works to a certain degree, but it's faking it. If it's something you need to do over and over, you could perhaps parse the records of the WMF and draw them with GDI+ antialiased.

The following threads back this up (but they're from 2005 so things might have changed):

http://www.dotnet247.com/247reference/msgs/28/144605.aspx

http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-sdk/1127/Graphics-DrawImage-metafile-no-antialiasing

[Edit:]

These three programs might do the job for you: I'm assuming you're ok with doing it by hand:

http://emf-to-vector-converter-command-line-ser.smartcode.com/info.html

http://www.verypdf.com/pdf-editor/index.html

http://www.ivanview.com/converter/emf-batch-converter.html

[Edit II:]

Well, here's a program that will let you inspect an EMF in various ways:

http://download.cnet.com/windows/3055-2383_4-10558240.html?tag=pdl-redir

...and here's a freeware library that will let you parse 122 of the EMF commands and output them in GDI+. That should probably do the trick:

http://www.codeproject.com/KB/GDI-plus/emfexplorer.aspx?msg=2359423

...oh, and notice also comment #3 on the codeproject page. Looks like someone have banged their heads against the wall before. Hope this solves your problem.

Pedery
  • 3,632
  • 1
  • 27
  • 39
  • Those programs just seem to convert it to other file formats. We chose EMF to display the vector art because this is the only vectorformat that GDI+ can handle. We need to draw the art from code (hence GDI+) because we modify it dynamically at runtime and animate it. Also displaying emf with GDI+ is most likely the most CPU- and memory friendly way to display vector art. Using another format that emf just doesn't seem helpful. A cool solution would be to have a Vectorgrafik (any format) to C# GDI+ instrructions converter. – bitbonk Nov 26 '09 at 12:02
  • In that case, why don't you use a retained mode drawing system and omit EMF alltogether? In theory you could store the EMF images and use a custom library to extract each shape and draw them again with GDI(+). However, from your description of the problem, I would have created a proprietary format that just *describes* the images using objects, then render it to whatever surface in question. A different approach could be to use swf, which is far better supported, well documented, and IMO more versatile. – Pedery Nov 26 '09 at 16:55
  • We cannot use a propietary format because we need to draw the art with a common drawing software (illustrator, inkscape, coreldraw ... one of those). – bitbonk Nov 26 '09 at 22:13
4

EMF is using GDI commands, not GDI+, so it has no notion of antialiasing. I suspect that when you ask GDI+ to render the file, it sends it to GDI and just copies the resulting bitmap.

Duplicating this in code would be the same as reimplementing GDI, so it's not terribly feasible. Not impossible, just a larger job than the benefit would justify. If there is an open source utility that can open EMF files outside of Windows, you might look into the source code.

My guess is that Word is using the downsampling trick.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
3

EMF file is a list of GDI commands. So it won't be anti-aliaised, even if under GDI+, you put a SmoothingMode() call before the drawing. You'll have to enumerate the GDI commands, then translate it into GDI+ commands.

Under Vista/Seven, you can use GDI+ 1.1 function named GdipConvertToEmfPlus/ConvertToEmfPlus. If you want your program to work with XP, you should write your own enumeration, then conversion to GDI+ commands.

The GDI enumeration then conversion to GDI+ is possible has been done by emfexplorer, but I've written some code perhaps more easy to follow, even if it's written in Delphi.

I'm putting this answer just now (I'm late), because I spent a lot of time finding out a solution using ConvertToEmfPlus, and writing some tuned open source code in case this method is not available.

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159