How to output Metafile (emf) into stream (or byte[])

903 views Asked by At

For an application I'm currently developing, I need to create a .emf file. I've got it working when I output the result directly to a file, but I can't get it to output into a stream, which is essential to what I'm trying to do.

This code correctly generates the file, but it's outputted directly to the harddisk.

var sizedImage = new Bitmap(103, 67);
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile("result.emf", graphicsFromSizedImage.GetHdc()))
using(var graphics = Graphics.FromImage(metafile))
{
    graphics.DrawStuff()
    graphicsFromSizedImage.ReleaseHdc();
}

Here's my attempt to output it to a memorystream, so I could get a byte[] from that stream:

byte[] resultingBytes;
var sizedImage = new Bitmap(103, 67);
using(var stream = new MemoryStream())
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc()))
using(var graphics = Graphics.FromImage(metafile))
{
    graphics.DrawStuff()
    graphicsFromSizedImage.ReleaseHdc();
    resultingBytes = stream.GetBuffer();
}
File.WriteAllBytes("result.emf", resultingBytes);

But all this does is create an empty file. When I run through it with the debugger, I can see the stream remain empty. What am I missing here..?

1

There are 1 answers

0
Dries Geenen On

I found the answer thanks to @Selvin

It turns out, the changes are only written to the MemoryStream when the "graphics" object is disposed. So, just by adding an extra set of brances, the problem is resolved.

Here's my working code:

byte[] resultingBytes;
var sizedImage = new Bitmap(103, 67);
using(var stream = new MemoryStream())
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc()))
{
    using(var graphics = Graphics.FromImage(metafile))
    {
        graphics.DrawStuff()
        graphicsFromSizedImage.ReleaseHdc();
    }
    resultingBytes = stream.ToArray();
}
File.WriteAllBytes("result.emf", resultingBytes);

Edit: As some have pointed out, stream.GetBuffer() will return the entire buffer. I changed it to stream.ToArray(), which should be better.