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.