Archive

Posts Tagged ‘DrawImage’

Overlay images with GDI

July 8, 2013 2 comments

Having good icons in your applications can really help users understand the relationships between their actions and the data. As a programmer you want to spend less time creating icons and more time implementing your features. This article shows you how to combine images at runtime to create state images or simply to add overlays to an image.

State images are used in many applications. For example in Visual Studio they are used to represent the source control status of a file:

State Images

Such images are typically 24 pixels wide by 16 pixels high. In this example the state portion of the image is 8×16 while the file icon is 16×16. Assuming you have an 8×16 PNG image for each FileStatus, here’s how you would combine then with a simple extension method (assuming you have pre-populated a dictionary with status images):

public static Image WithStatus(this Image image, FileStatus status)
{
    if (image == null)
        throw new ArgumentNullException("image");

    Image result = new Bitmap(24, 16);
    using (Graphics g = Graphics.FromImage(result))
    {
        g.DrawImage(_statusImages[status], 0, 0, 8, 16);
        g.DrawImage(image, 8, 0, 16, 16);
    }
    return result;
}

In other scenarios you might just need to add an overlay without changing the original size of your image:

Overlay1 Overlay2Overlays

To accomplish this you can use the following extension method:

public static Image WithOverlay(this Image image, Image overlay)
{
    if (image == null)
        throw new ArgumentNullException("image");

    if (overlay == null)
        throw new ArgumentNullException("overlay");

    int width = image.Width;
    int height = image.Height;
    Image result = new Bitmap(width, height);
    using (Graphics g = Graphics.FromImage(result))
    {
        Rectangle rect = new Rectangle(0, 0, width, height);
        g.DrawImage(image, rect);
        g.DrawImage(overlay, rect);
    }
    return result;
}

The nice thing with extension methods is that you can combine them programmatically to create powerful transformations with a single line of code:

return image.Disabled(true).WithOverlay(overlay).WithStatus(status);

GDI is relatively fast enough to create those bitmaps on the fly at runtime. You can obviously cache the resulting images if the performance becomes an issue though. This solution works well if you are using Windows Forms but I would not recommend it with WPF as there are better approaches. You might have noticed the Disabled() method in the snippet above. In the next article I’ll show how to create a disabled image with GDI.

Advertisements