Monday, 21 November 2011

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.BeginInit();
   bitmap.DecodePixelWidth = 80;
   bitmap.DecodePixelHeight = 60;
   bitmap.StreamSource = memoryStream;
   bitmap.EndInit();
   bitmap.Freeze();
 
   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));
 
 

No comments:

Post a Comment