Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

.net

svg

.emf

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();
}
like image 265
nevets Avatar asked Oct 01 '14 22:10

nevets


1 Answers

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.

like image 194
Skaiol Avatar answered Sep 23 '22 02:09

Skaiol