TheDeveloperBlog.com


C# Image Type

Images are complex and there are many image formats. With the Image type in the C# language and .NET Framework, you can act upon an abstraction of all those image types. This greatly simplifies image-handling code.


Constructor. There is no constructor for the Image type. Instead, look into using the Image.FromFile or Image.FromStream methods. These will return a new instances of the Image type. They are static methods.

Static Method

FromFile. The FromFile method is the easiest way to get an instance of a new Image in memory. Internally, FromFile uses functions from the GDI+ libraries of Microsoft Windows. This example program demonstrates the usage of Image.FromFile.

Tip: The easiest way to use Image.FromFile is to pass it a single argument: the file name. Then, you can access the Image object itself.

C# program that uses Image.FromFile

using System;
using System.Drawing;

class Program
{
    static void Main()
    {
	string[] array =
	{
@"C:\thumbnail.png",
@"C:\Users\Sam2\Documents\perls\main\images\bluearrow1.png"
	};

	foreach (string fileName in array)
	{
	    Image image = Image.FromFile(fileName);
	    int width = image.Width;
	    int height = image.Height;

	    Console.WriteLine("{0}: {1} {2}", fileName, width, height);
	}
    }
}

Output

C:\thumbnail.png: 9 40
C:\Users\Sam2\Documents\perls\main\images\bluearrow1.png: 208 208

How does the Image.FromFile method work? Inside the .NET Framework, this method uses the gdiplus.dll library. It checks errors and calls into native code. This method would be hard to implement on your own.

Tip: Because it goes into native code and external libraries, it is probably faster to use caching to reduce calls to Image.FromFile.


Image.FromStream. The Image.FromStream method works the same as the FromFile method but acts upon a Stream instance to get the image data. This means you can get an Image from a byte array in memory with a MemoryStream, or a file with FileStream.

File.Open Examples
C# program that uses Image.FromStream method

using System;
using System.Drawing;
using System.IO;

class Program
{
    static void Main()
    {
	using (FileStream stream = File.Open("C:\\t4\\2Z", FileMode.Open))
	using (Image image = Image.FromStream(stream))
	{
	    Console.WriteLine(image.Size);
	}
    }
}

Output

{Width=280, Height=248}


Tag. You can also assign any object reference to the Tag property. The Tag here is much like the Tag property in Windows Forms. It is a place you can attach a reference of any type in memory.

Tag in Windows Forms
C# program that uses Tag property

using System;
using System.Drawing;

class Program
{
    static void Main()
    {
	using (Image image = Image.FromFile("C:\\t4\\2Z"))
	{
	    image.Tag = "Dot Net Perls image";
	    // Do stuff.
	    Console.WriteLine(image.Tag);
	}
    }
}

Output

Dot Net Perls image


Resolution. Most bitmap images, such as PNG files and JPG files, will have a HorizontalResolution and VerticalResolution of 72 each. This is a pretty standard number. It is possible for some images to have a different resolution.

C# program that accesses resolution

using System;
using System.Drawing;

class Program
{
    static void Main()
    {
	Image i = Image.FromFile("C:\\t4\\2Z");
	float h = i.HorizontalResolution;
	float v = i.VerticalResolution;
	Console.WriteLine("{0}, {1}", h, v);
    }
}

Output

72, 72


RotateFlip. If you need to rotate or flip an image, the RotateFlip method is just what you need. The method allows you to both rotate and flip in a single method call. In this program, I call RotateFlip with its enumerated constants.

Note: The image used was on the front page of this site. It has text on it, so you can tell how the image was rotated and flipped.

C# program that flips image with RotateFlip

using System;
using System.Drawing;

class Program
{
    const string _input = "C:\\t4\\2Z";

    static void Main()
    {
	M(RotateFlipType.Rotate180FlipNone);
	M(RotateFlipType.Rotate180FlipX);
	M(RotateFlipType.Rotate180FlipXY);
	M(RotateFlipType.Rotate180FlipY);
	M(RotateFlipType.Rotate270FlipNone);
	M(RotateFlipType.Rotate270FlipX);
	M(RotateFlipType.Rotate270FlipXY);
	M(RotateFlipType.Rotate270FlipY);
	M(RotateFlipType.Rotate90FlipNone);
	M(RotateFlipType.Rotate90FlipX);
	M(RotateFlipType.Rotate90FlipXY);
	M(RotateFlipType.Rotate90FlipY);
	M(RotateFlipType.RotateNoneFlipNone);
	M(RotateFlipType.RotateNoneFlipX);
	M(RotateFlipType.RotateNoneFlipXY);
	M(RotateFlipType.RotateNoneFlipY);
    }

    static void M(RotateFlipType type)
    {
	Image i = Image.FromFile(_input);
	i.RotateFlip(type);
	i.Save("C:\\" + type.ToString() + ".png");
    }
}

Output
    Some selected images are shown below.

First is Rotate90FlipXY. This is an old Dot Net Perls logo rotated 90 degrees and then flipped both horizontally and vertically. Next we see Rotate180FlipY, Rotate270FlipX, Rotate270FlipXY and RotateNoneFlipY.


GetThumbnailImage. To save bandwidth, websites often use thumbnail images that users can click on to see larger versions. Depending on the type of website in question, users may be able to visually tell what interests them quickly.

Tip: The GetThumbnailImage method provides more information and a scaling algorithm for thumbnail images.

Thumbnail Image With GetThumbnailImage

Dispose. Because the Image type implements IDisposable, it can be used with the using statement in a resource acquisition block. If your program has strict memory limits, the using statement often helps. It disposes the Image.

Using Statement: Dispose and IDisposable

Height, Width. The Height and Width properties on the Image type is useful as well. This can be used to generate HTML files that contain the height and width attributes for an image that is on the disk.

Also: The Size property on the Image type is another representation of the Height and Width values.

To begin, place an image file (such as a PNG) somewhere on your computer. Then, add the System.Drawing namespace to your C# project. If the namespace is not found, add the assembly reference System.Drawing.

Next: Use the code shown below to open the Image (with Image.FromFile), and then access the Width, Height, or PhysicalDimension properties.

C# program that gets image width and height

using System;
using System.Drawing;

class Program
{
    static void Main()
    {
	Image image = Image.FromFile("C:\\background1.png", false);
	Console.WriteLine(image.Width);
	Console.WriteLine(image.Height);
	Console.WriteLine(image.PhysicalDimension);
    }
}

Output

180
110
{Width=180, Height=110}

Image formats. Obviously, not all image formats are supported by the Image type. The PNG type is supported. More exotic types such as Photoshop image formats would not be supported.

If your application requires the width and height of an image to be known, you do not need to hard-code that data inside your program. Instead, you can use the Image type to get the information directly from the file.

And: The best part is that you do not need to do anything directly with the bytes of the file.


Save. After providing a target file name, the Save method will write the image data in memory to the location. This is useful after rotating or resizing an image. The RotateFlip example has an example usage of the Save method.

The SaveAdd method allows you to add extra frames to an existing image on the disk. The concept of frames is relevant for when you are working with only some kinds of images such as TIFF images that support multiple pages or frames.

Frames: Many of the methods available on the Image type refer to the concept of frames.

Tip: This concept is only relevant for some kinds of images, such as TIFF. A frame may represent a page in a multi-page image.


Images are important. We explored many different aspects of the Image type in the .NET Framework using the C# language. With abstraction, the Image type allows us to use image formats in a simple way, but with limitations.

Also: Rotating, flipping and resizing are possible. More complex transformations introduce greater challenges.