Click here to Skip to main content
15,891,431 members
Articles / Desktop Programming / WPF

WPF Interactive Image Cropping Control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (60 votes)
6 Sep 20078 min read 413K   11.6K   146  
WPF Interactive Image Cropping Control
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ImageCropper
{
    /// <summary>
    /// Provides a Canvas where a rectangle will be drawn
    /// that matches the selection area that the user drew
    /// on the canvas using the mouse
    /// </summary>
    public partial class SelectionCanvas : Canvas
    {
        #region Instance fields
        private Point mouseLeftDownPoint;
        private Style cropperStyle;
        public Shape rubberBand = null;
        public readonly RoutedEvent CropImageEvent;
        #endregion

        #region Events
        /// <summary>
        /// Raised when the user has drawn a selection area
        /// </summary>
        public event RoutedEventHandler CropImage
        {
            add { AddHandler(this.CropImageEvent, value); }
            remove { RemoveHandler(this.CropImageEvent, value); }
        }
        #endregion

        #region Ctor
        /// <summary>
        /// Constructs a new SelectionCanvas, and registers the 
        /// CropImage event
        /// </summary>
        public SelectionCanvas()
        {
            this.CropImageEvent = EventManager.RegisterRoutedEvent("CropImage",
                RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SelectionCanvas));
        }
        #endregion

        #region Public Properties
        public Style  CropperStyle
        {
            get { return cropperStyle; }
            set { cropperStyle = value; }
        }
        #endregion

        #region Overrides

        /// <summary>
        /// Captures the mouse
        /// </summary>
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            if (!this.IsMouseCaptured)
            {
                mouseLeftDownPoint = e.GetPosition(this);
                this.CaptureMouse();
            }
        }

        /// <summary>
        /// Releases the mouse, and raises the CropImage Event
        /// </summary>
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);

            if (this.IsMouseCaptured && rubberBand != null)
            {
                this.ReleaseMouseCapture();

                RaiseEvent(new RoutedEventArgs(this.CropImageEvent, this));
            }
        }

        /// <summary>
        /// Creates a child control <see cref="System.Windows.Shapes.Rectangle">Rectangle</see>
        /// and adds it to this conrtols children collection at the co-ordinates the user
        /// drew with the mouse
        /// </summary>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this.IsMouseCaptured)
            {
                Point currentPoint = e.GetPosition(this);

                if (rubberBand == null)
                {
                    rubberBand = new Rectangle();
                    if (cropperStyle != null)
                        rubberBand.Style = cropperStyle;
                      //rubberBand.Stroke = new SolidColorBrush(Colors.LightGray);
                    //rubberBand.Fill = Brushes.Yellow;
                    //rubberBand.Opacity = 0.20;
                    this.Children.Add(rubberBand);
                }

                double width = Math.Abs(mouseLeftDownPoint.X - currentPoint.X);
                double height = Math.Abs(mouseLeftDownPoint.Y - currentPoint.Y);
                double left = Math.Min(mouseLeftDownPoint.X, currentPoint.X);
                double top = Math.Min(mouseLeftDownPoint.Y, currentPoint.Y);

                rubberBand.Width = width;
                rubberBand.Height = height;
                Canvas.SetLeft(rubberBand, left);
                Canvas.SetTop(rubberBand, top);
            }
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions