Displaying Images


One of the most common things you might want to do with GDI+ is display an image that already exists in a file. This is actually a lot simpler than drawing your own user interface, because the image is already pre-drawn. Effectively, all you have to do is load the file and instruct GDI+ to display it. The image can be a simple line drawing, an icon, or a complex image such as a photograph. You can also manipulate the image by stretching or rotating it, or simply displaying only a portion of it.

This section, just for a change, presents the sample first. Then it discusses some of the issues you need to be aware of when displaying images. Presenting it this way is possible because the code needed to display an image is so simple.

The class you need is the .NET base class, System.Drawing.Image. An instance of Image represents one image. Reading in an image simply takes one line of code:

  Image myImage = Image.FromFile("FileName"); 

FromFile() is a static member of Image and is the usual way of instantiating an image. The file can be any of the commonly supported graphics file formats, including .bmp, .jpg, .gif, and .png.

Displaying an image is also very simple, assuming that you have a suitable Graphics instance at hand - a call to either Graphics.DrawImageUnscaled() or Graphics.DrawImage() suffices. There are quite a few overloads of these methods, allowing you a lot of flexibility in the information you supply in terms of where the image is located and how big it is to be drawn. But this example uses DrawImage(), like this:

  dc.DrawImage(myImage, points); 

In this line of code, dc is assumed to be a Graphics instance, and myImage is the Image to be displayed. points is an array of Point structs, where points[0], points[1], and points[2] are the coordinates of top-left, top-right, and bottom-left corner of the image.

Tip 

Images are probably the area in which developers familiar with GDI will notice the biggest difference between GDI and GDI+. In GDI, displaying an image involved several nontrivial steps. If the image was a bitmap, loading it was reasonably simple. But if it was any other file type, loading it would involve a sequence of calls to OLE objects. Actually getting a loaded image onto the screen involved getting a handle to it, selecting it into a memory device context, and then performing a block transfer between device contexts. Although the device contexts and handles are still there behind the scenes, and will be needed if you want to start doing sophisticated editing of the images from your code, simple tasks have now been extremely well wrapped up in the GDI+ object model.

The process of displaying an image is illustrated with an example called DisplayImage. The example simply displays a .jpg file in the application’s main window. To keep things simple, the path of the .jpg file is hard-coded into the application (so if you run the example you’ll need to change it to reflect the location of the file in your system). The .jpg file you’ll display is a sunset picture in London.

As with the other examples, the DisplayImage project is a standard C# Visual Studio 2005 generated Windows application. You add the following fields to your Form1 class:

  Image piccy; private Point [] piccyBounds; 

You then load the file in the Form1() constructor:

  public Form1() {    InitializeComponent();    piccy =       Image.FromFile(@"C:\ProCSharp\GdiPlus\Images\London.jpg");    this.AutoScrollMinSize = piccy.Size;    piccyBounds = new Point[3];    piccyBounds[0] = new Point(0,0);      // top left    piccyBounds[1] = new Point(piccy.Width,0);   // top right    piccyBounds[2] = new Point(0,piccy.Height);   // bottom left } 

Note that the size in pixels of the image is obtained as its Size property, which you use to set the document area. You also set up the piccyBounds array, which is used to identify the position of the image on the screen. You have chosen the coordinates of the three corners to draw the image in its actual size and shape here, but if you’d wanted the image to be resized, stretched, or even sheared into a nonrectangular parallelogram, you could do so simply by changing the values of the Points in the piccyBounds array.

The image is displayed in the OnPaint() override:

  protected override void OnPaint(PaintEventArgs e) {    base.OnPaint(e);    Graphics dc = e.Graphics;    dc.ScaleTransform(1.0f, 1.0f);    dc.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);    dc.DrawImage(piccy, piccyBounds); } 

Finally, note the modification made to the code wizard-generated Form1.Dispose() method:

 protected override void Dispose(bool disposing) {    piccy.Dispose();    if( disposing )    {       if (components != null)       {          components.Dispose();       }    }    base.Dispose( disposing ); }

Disposing of the image as soon as possible when it’s no longer needed is important, because images generally take up a lot of memory while in use. After Image.Dispose() has been called, the Image instance no longer refers to any actual image, and so it can no longer be displayed (unless you load a new image).

Figure 30-14 shows the result of running this code.

image from book
Figure 30-14




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net