Techniques - DevSource
DevSource: Microsoft Developer Resource DevSource Home Sponsored by Microsoft Home Add Ons Architecture Languages Techniques Using VS Forums
Home arrow Techniques arrow Page 3 - I Never Metafile I Didn't Like
I Never Metafile I Didn't Like
By Peter Aitken

Rate This Article: Add This Article To:

I Never Metafile I Didn't Like - ' Creating a New Metafile '
( Page 3 of 3 )

Creating a New Metafile

You can use the tools in the .Net Framework to create a new metafile and draw an image in it. The Metafile class has numerous constructors. The three I use the most are Metafile(FileName), Metafile(FileName, IntPtr), and Metafile(IntPtr, Rectangle).

ADVERTISEMENT

The first two constructors create the metafile in memory while automatically writing it to the specified file. The third one creates the metafile in memory only using the bounding box specified by the Rectangle structure. In the second two examples, the IntPtr argument is a pointer to the device context that is used to create the metafile.

So, what's a device context? It's a way that the Windows operating system encapsulates information about a display device, such as the video screen or a printer. If you create a metafile based on a specific display device, then the resolution of the metafile will be optimized for reproduction on that device. If you create a metafile without reference to a device context the result will not be optimized for any particular device.

You get a device context from a Graphics object. For the video display, you do it like this:

Graphics g = this.CreateGraphics();
IntPtr pHdc = g.GetHdc();

And for the default printer, like this:

PrinterSettings ps = new PrinterSettings();
Graphics g = ps.CreateMeasurementGraphics(); 
IntPtr pHdc = g.GetHdc();

After using the device context to create the metafile, be sure to release it and, if you won't be using it again, dispose of the Graphics object:

g.ReleaseHdc(pHdc);
g.Dispose();

Drawing in a Metafile

Figure 2. The metafile image created by the example listing

After you create the new metafile, it is empty. You add drawing items to the metafile by creating a Graphics object based on it and then calling the Graphics object's drawing methods. The listing below gives an example with the output shown in Figure 2.

private void button1_Click(object sender, EventArgs e)
{
Graphics g = CreateGraphics();
IntPtr pHdc = g.GetHdc();
Metafile mf = new Metafile("c:\\test.emf", pHdc);
g.ReleaseHdc(pHdc);
g.Dispose();
g = Graphics.FromImage(mf);
g.DrawRectangle(Pens.Black, 10, 10, 390, 230);
g.FillRectangle(Brushes.Red, 20, 20, 370, 210);
g.FillEllipse(Brushes.Green, 160, 100, 100, 100);
Font f = new Font("Arial", 40);
g.DrawString("metafiles rule!", f, Brushes.Blue, 30, 40);
g.Dispose();
g = this.CreateGraphics();
g.DrawImage(mf,0,0);

Converting a Metafile to a Bitmap

If you have a metafile but need a bitmap, the conversion is easy; you cannot convert the other way, however. I won't go into the details, but the function given here, which is passed a metafile and returns a bitmap of the same image, shows you how its done.

Bitmap BitmapFromMetafile(Metafile mf)
{
g = this.CreateGraphics();
int BitmapWidth = (int)(g.DpiX * mf.Width / mf.HorizontalResolution);
int BitmapHeight = (int)(g.DpiY * mf.Height / mf.VerticalResolution);
Bitmap bmp = new Bitmap(BitmapWidth, BitmapHeight, g);
g.Dispose();
g = Graphics.FromImage(bmp);
g.DrawImage(mf, 0, 0, BitmapWidth, BitmapHeight);
g.Dispose();
return bmp;
}

Summary

Metafiles are one of two fundamental ways of representing an image. While they are not suitable for all images, photographs in particular, they have many advantages over bitmaps for charts and drawings.



 
 
>>> More Techniques Articles          >>> More By Peter Aitken
 



Microsoft's Future: A Chat With Their CTO, Barry Briggs

Play Video >

All Videos >

Julia explores the Robotics Studio!

Read now >

Messages to Bill Gates!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.