Bookmark and Share Share...    Subscribe to this feed Feed   About Christian Moser  

Images in WPF

How to set the Icon of a Window

If you try to set the Window.Icon from Codebehind, you probably get the error ImageSource for Icon property must be an icon file.. You can use the following snippet to do the trick:

var icon = BitmapFrame.Create(Application.GetResourceStream(
   new Uri("MyAppIcon.ico", UriKind.RelativeOrAbsolute)).Stream);

Note: You can get an "Image format is unrecognized" exception under XP, if the icon only contains compressed PNG files. In this case you have to recreate the icon without compression.

How to create a Thumbnail of an Image

private ImageSource GetThumbnail( string fileName )
   byte[] buffer = File.ReadAllBytes(fileName);
   MemoryStream memoryStream = new MemoryStream(buffer);
   BitmapImage bitmap = new BitmapImage();
   bitmap.DecodePixelWidth = 80;
   bitmap.DecodePixelHeight = 60;
   bitmap.StreamSource = memoryStream;
   return bitmap;

How to automatically crop an image

The following method allows you to automatically crop an image to it's content.

public static ImageSource AutoCropBitmap(BitmapSource source)
    if (source == null)
        throw new ArgumentException("source");
    if (source.Format != PixelFormats.Bgra32)
        source = new FormatConvertedBitmap(source, 
                            PixelFormats.Bgra32, null, 0);
    int width = source.PixelWidth;
    int height = source.PixelHeight;
    int bytesPerPixel = source.Format.BitsPerPixel / 8;
    int stride = width * bytesPerPixel;
    var pixelBuffer = new byte[height * stride];
    source.CopyPixels(pixelBuffer, stride, 0);
    int cropTop = height, cropBottom = 0, cropLeft = width, cropRight = 0;
    for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
            int offset = (y * stride + x * bytesPerPixel);
            byte blue = pixelBuffer[offset];
            byte green = pixelBuffer[offset + 1];
            byte red = pixelBuffer[offset + 2];
            byte alpha = pixelBuffer[offset + 3];
            //TODO: Define a threshold when a pixel has a content
            bool hasContent = alpha > 10;
            if (hasContent)
                cropLeft = Math.Min(x, cropLeft);
                cropRight = Math.Max(x, cropRight);
                cropTop = Math.Min(y, cropTop);
                cropBottom = Math.Max(y, cropBottom);
    return new CroppedBitmap(source, 
             new Int32Rect(cropLeft, cropTop, cropRight - cropLeft, 
                           cropBottom - cropTop));

How to flip an image horizontally or vertically

The easiest way to flip an image in WPF is to use a TransformedBitmap. It's a wrapper around a BitmapImage that takes a generic Transform object.

var flippedImage = new TransformedBitmap(originalImage, new ScaleTransform( -1,1));

Last modified: 2011-03-01 08:43:30
Copyright (c) by Christian Moser, 2011.

 Comments on this article

Show all comments
Commented on 1.November 2009
Very nice code. I have a question though, say you have a 3 images (png, jpeg, etc). One is the regular image, one for mouseover and one for mousedown. Is there any way in Expression 3 or code to do an event while still maintaining the button aspect. Meaning, is there a way to make a rollover event using 3 images?
Christian Moser
Commented on 1.November 2009
Hi Curtis,
I did not exactly understood your question. Is it correct, that you would like to build a button that has a normal, a mouseover and a pressed appearance?

If that was your question, you can create a style with triggers. Triggers are conditions within a style, who can switch the source of the image, when the mouse hovers over the button or the button is pressed.

I hope this helps.

Commented on 17.December 2009

Very good code, however are there any examples on image move in the canvas. For example I have a football image and have placed in the canvas, when ever I move my mouse it should move within the canvas and shouldn't go outside.
Commented on 27.April 2010
yeah excellent code
Commented on 2.June 2010
Good code but you are wasting much memory, because of:
bitmap.StreamSource = memoryStream;

That is a reference on the stream which will be available until the Image itself is destryoed, so you are holding the Memory for the real Image AND the thumbnail!

Better solution for me is to creating a
WriteableBitmap bmp = new WriteAbleBitmap(bitmap);
And Dispose the stream:
memorystream = null;

(Better Solution is using the "Using" statement)
and returning only the thumbnail!

ps.: Some Websites recomment that you freeze() the Bitmaps to confirm that the memory is beeing released after use
Commented on 9.June 2010
Show outputs of above examples
Commented on 16.July 2010
How do I move an image with code ie, I want to center an image inside a grid keeping the image hight/width ratio
Ayyappa INDIA
Commented on 18.February 2011
Excellent Christian Moser,
We need elaborate description and Examples.


E-Mail (optional)