How to convert an SVG file to an EMF file in C#
Asked Answered
C

2

9

It's definitely possible to convert an SVG to EMF, for example this website. I wonder if it's possible to achieve this conversion in C#?


Update:

I tried to read an SVG file using SVG.NET and draw it to a Graphics object, then tried export the Image as a MetaFile in .emf extension (I followed the instruction here: GDI+ / C#: How to save an image as EMF?). The reading was done successfully and the image did get exported as .emf. However, when I opened that .emf in PowerPoint, it couldn't be un-grouped, which indicated that the drawing info of that file was actually not dumped correctly.

Update 2:

Now it does export a ungroup-able .emf, but the ungrouping shows a really poor result. I used the following code to produce the .emf:

private void OpenPictureButtonClick(object sender, EventArgs e)
{
    var openFileDialog = new OpenFileDialog();
    openFileDialog.ShowDialog();

    _svgDoc = SvgDocument.Open(openFileDialog.FileName);

    RenderSvg(_svgDoc);
}

private void SavePictureClick(object sender, EventArgs e)
{
    var saveFileDialog = new SaveFileDialog {Filter = "Enhanced Meta File | *.Emf"};
    saveFileDialog.ShowDialog();

    var path = saveFileDialog.FileName;
    var graphics = CreateGraphics();
    var img = new Metafile(path, graphics.GetHdc());
    var ig = Graphics.FromImage(img);

    _svgDoc.Draw(ig);

    ig.Dispose(); img.Dispose(); graphics.ReleaseHdc(); graphics.Dispose();
}

private void RenderSvg(SvgDocument svgDoc)
{
    svgImageBox.Image = svgDoc.Draw();
}
Clarendon answered 1/10, 2014 at 22:52 Comment(0)
W
10

I had the same issue but searching had no results.
Finally I ended up with my own simple solution below. I used SVG.NET.

public static byte[] ConvertToEmf(string svgImage)
{
    string emfTempPath = Path.GetTempFileName();
    try
    {
        var svg = SvgDocument.FromSvg<SvgDocument>(svgImage);
        using (Graphics bufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
        {
            using (var metafile = new Metafile(emfTempPath, bufferGraphics.GetHdc()))
            {
                using (Graphics graphics = Graphics.FromImage(metafile))
                {
                    svg.Draw(graphics);
                }
            }
        }

        return File.ReadAllBytes(emfTempPath);
    }
    finally
    {
        File.Delete(emfTempPath);
    }
}

At first I create a temp file. Then I use Draw(Graphics) method to save emf in it. And at last I read bytes from temp file.
Don't try to use MemoryStream for Metafile. Unfortunately, it's not working.

Werth answered 14/9, 2015 at 15:18 Comment(2)
it has been around a year and finally :) I will try your solution and come back to you soon :)Clarendon
Any idea how to do reverse? From .emf to .svg?Undersecretary
S
0

This is what I found to be currently the best solution. This is almost like the accepted answer and uses SVG.NET, but is capable of doing it in memory.

The important changes are to release the handle and to reset the position memory stream.

public static Stream ConvertSvgToEmf(string svgImage)
{
    using var writeStream = new MemoryStream();

    var svg = SvgDocument.FromSvg<SvgDocument>(svgImage);
    var stream = new MemoryStream();
    var sizedImage = new Bitmap((int)svg.Width.Value, (int)svg.Height.Value);
    using (var graphicsFromSizedImage = Graphics.FromImage(Image.FromHbitmap(sizedImage.GetHbitmap())))
    using (var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc(), EmfType.EmfPlusOnly)) // Specify EmfType for lesser file size
    using (var graphics = Graphics.FromImage(metafile))
    {
        svg.Draw(graphics);
        graphicsFromSizedImage.ReleaseHdc();
    }

    stream.Position = 0;

    return stream;
}

Be aware that the underlying implementation relies on System.Drawing and therefore the gdi must be accessible. On linux based OS's (or Docker images) libgdiplus must be installed.

As System.Drawing is considered to be deprecated, alternatives like Magick.NET may be better suited for your case.

Su answered 5/6, 2021 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.