February 6, 2009

System.Drawing.Image Extension Class

Adds simple methods for redrawing images with a given interpolation mode whilst maintaining the aspect ratio.
/// <summary>
/// System.Drawing.Image Extender
/// </summary>
public static class ImageExtender
{

  /// <summary>
  /// Resize the given image to the targetSize using the given interpolation mode
  /// Keeps the existing aspect ratio of the image
  /// </summary>
  /// <param name="srcImage"></param>
  /// <param name="targetSize"></param>
  /// <param name="im"></param>
  /// <returns></returns>
  public static Image ResizeImage(this Image srcImage, Size targetSize, InterpolationMode im)
  {
    Rectangle srcRect = new Rectangle(0, 0, srcImage.Width, srcImage.Height);

    Size sizeToFit = CalcSizeToFit(srcImage.Size, targetSize);
    Rectangle destRect = new Rectangle(0, 0, sizeToFit.Width, sizeToFit.Height);

    Bitmap resizedImage = new Bitmap(sizeToFit.Width, sizeToFit.Height, PixelFormat.Format24bppRgb);
    resizedImage.SetResolution(srcImage.HorizontalResolution, srcImage.VerticalResolution);

    Graphics imageAsCanvas = Graphics.FromImage(resizedImage);
    imageAsCanvas.Clear(Color.White);
    //imageAsCanvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
    imageAsCanvas.InterpolationMode = im;

    imageAsCanvas.DrawImage(srcImage,
      destRect,
      srcRect,
      GraphicsUnit.Pixel);

    imageAsCanvas.Dispose();
    return resizedImage;
  }

  /// <summary>
  /// Resize the given image to the targetSize using bicubic interpolation
  /// Keeps the existing aspect ratio of the image
  /// </summary>
  /// <param name="srcImage"></param>
  /// <param name="targetSize"></param>
  /// <param name="im"></param>
  /// <returns></returns>
  public static Image ResizeImageHighQuality(this Image srcImage, Size targetSize)
  {
    Rectangle srcRect = new Rectangle(0, 0, srcImage.Width, srcImage.Height);

    Size sizeToFit = CalcSizeToFit(srcImage.Size, targetSize);
    Rectangle destRect = new Rectangle(0, 0, sizeToFit.Width, sizeToFit.Height);

    Bitmap resizedImage = new Bitmap(sizeToFit.Width, sizeToFit.Height,
            PixelFormat.Format24bppRgb);
    resizedImage.SetResolution(srcImage.HorizontalResolution,
            srcImage.VerticalResolution);

    using (Graphics imageAsCanvas = Graphics.FromImage(resizedImage))
    {
      imageAsCanvas.Clear(Color.White);
      imageAsCanvas.InterpolationMode = InterpolationMode.HighQualityBicubic;

      imageAsCanvas.DrawImage(srcImage,
          destRect,
          srcRect,
          GraphicsUnit.Pixel);

    }
    return resizedImage;
  }


  /// <summary>
  /// Calculate the best fit of the source size to the target 
  /// size that maintains the aspect ratio
  /// </summary>
  /// <param name="src"></param>
  /// <param name="target"></param>
  /// <returns></returns>
  static public Size CalcSizeToFit(Size src, Size target)
  {
    float sfh = (float)target.Height / (float)src.Height;
    float sfw = (float)target.Width / (float)src.Width;
    float sf = Math.Min(sfh, sfw);
    Size sizeToFit = new Size((int)Math.Round((double)src.Width * sf),
      (int)Math.Round((double)src.Height * sf));
    return sizeToFit;
  }
}

February 5, 2009

Using Application Commands

These are standard application related commands, see here In Xaml:
  <Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Close"
                    Executed="CloseCommandHandler"
                    CanExecute="CanExecuteHandler"
                    />
  </Window.CommandBindings>
...
  <Button Command="ApplicationCommands.Close" 
            Content="Close File" />
and in code:
// Executed event handler.
private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
    // Calls a method to close the file and release resources.
    CloseFile();
}

// CanExecute event handler.
private void CanExecuteHandler(object sender, CanExecuteRoutedEventArgs e)
{
    // Call a method to determine if there is a file open.
    // If there is a file open, then set CanExecute to true.
    if (IsFileOpened())
    {
        e.CanExecute = true;
    }
    // if there is not a file open, then set CanExecute to false.
    else
    {
        e.CanExecute = false;
    }
}