Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CropBox

0.00/5 (No votes)
21 Aug 2019 6  
Easily add image cropping to your desktop application

Introduction

So, this time, I was writing a desktop application where the user should be able to select a part of an image and save the cropped image.

Normally, I spend a lot of time and energy on searching the net and trying out existing controls before I start rolling my own, but in this case I didn't, because I was 99% certain right from the start that I wouldn't find any that would live up to my expectations.

So I started developing the control myself straight off. I wanted sort of a PictureBox that could show the image, with a selection rectangle that could be adjusted and so on.

Not much more to say. The control ended up better than I could ever have expected and extremely easy to use. So here it is. If you need it, just go ahead - otherwise don't...

Control Feature Overview

1) Basic Control Info

I derived the control from the standard Panel control. That way, it would get all the Panel properties and behaviour that makes it easy to design and layout your form.

Why didn't you derive it from a PictureBox, I can hear you ask? Good question! Don't know, really. I wanted the control to be as lightweight and simple as possible, and I thought that a Panel would be a better base for that than a PictureBox.

2) Properties You Need to Know About

As you will see later, the control is EXTREMELY simple to use. There are a handful of properties that are good to know about. Most of them have to do with the look of the control.

  • Image - The image property is where you assign the image you need to crop.
  • OverlayColor - The part of the image that is NOT selected is shown with a semitransparent overlay to make it easier to see the selection itself. You can set the color of the overlay here.
  • OverlayAlpha - The overlay is semitransparent, and the OverlayAlpha property determines just HOW transparent it is. The value should be between 0 (invisible) and 255 (completely opaque).
  • SelectionInitialMode determines what selection is shown automatically when you load the image. If you don't like the standard modes and select Custom, you should make sure to handle the SetInitialSelection event in your code. If you don't, the FullImage mode will be used.
  • SelectionResizeMode determines how you can resize the selection. It also determines if the corner handles are shown or not.
  • SelectionBorderColor, SelectionBorderDashStyle, SelectionBorderDashPattern and SelectionBorderWidth all determine how the border around the selected part of the image is drawn. SelectionBorderDashPattern is not visible in the designer, but should be set in code if you set SelectionBorderDashStyle to Custom. Otherwise, you can forget about it.
  • SelectionResizeHandleBorderColor, SelectionResizeHandleBorderWidth and SelectionResizeHandleColor determines how the resize handles in the corner are drawn (if they should be drawn at all, that is).
  • ThumbnailScalingPercentage - The control can generate a thumbnail for your cropped image if you want. This property determines how big it should be, in percent of the full image size.

New in version 1.2:

  • StartEditingMode - Determines when it should be possible to edit the Image.

3) Methods You Need to Know About

  • GetCroppedImage - Returns the image in the control cropped to the selected area.
  • GetCroppedImageThumbnail - Returns a thumbnail of the image in the control cropped to the selected area. Also see the ThumbnailScalingPercentage property.

New in version 1.2:

  • StartEdit and EndEdit - Call these methods to start the edit mode or end it.
  • SaveCroppedImage - Saves the cropped image directly to file
  • SaveCroppedImageThumbnail - Saves the cropped image thumbnail directly to file
  • ResetSelection - Resets the selection to the initial selection

Usage

Image 1

As mentioned, it is VERY easy and straightforward to use the control. Merely drop it on your form and adjust the size and look to your liking. Then assign an image to the Image property, for instance like this:

cropBox1.Image = Image.FromFile(fileName);

After that, you can edit the selection, and when you're ready to crop the image, you can get the cropped image like this:

Image croppedImage = cropBox1.GetCroppedImage();

After that, it's simple .NET programming to save the image to a Jpeg file:

croppedImage.Save(fileName, ImageFormat.Jpeg);

Tip

The control uses the entire client surface to paint the Image, but if you think that looks stupid, you can simply set the Padding property to get a border around the image.

Interesting Thing I Learned

The standard .NET functionality to load an image from file (see code above) doesn't care anything about the EXIF orientation tag. That means that if you've taken the photo using your smartphone, etc., it may be shown completely wrong when you load it into an Image class.

Luckily, it's easily fixed, and I have of course incorporated it in the control:

if (Array.IndexOf(_image.PropertyIdList, 274) > -1)
{
    var orientation = (int)_image.GetPropertyItem(274).Value[0];
    switch (orientation)
    {
        case 1:
            // No rotation required.
            break;
        case 2:
            _image.RotateFlip(RotateFlipType.RotateNoneFlipX);
            break;
        case 3:
            _image.RotateFlip(RotateFlipType.Rotate180FlipNone);
            break;
        case 4:
            _image.RotateFlip(RotateFlipType.Rotate180FlipX);
            break;
        case 5:
            _image.RotateFlip(RotateFlipType.Rotate90FlipX);
            break;
        case 6:
            _image.RotateFlip(RotateFlipType.Rotate90FlipNone);
            break;
        case 7:
            _image.RotateFlip(RotateFlipType.Rotate270FlipX);
            break;
        case 8:
            _image.RotateFlip(RotateFlipType.Rotate270FlipNone);
            break;
    }

    // This EXIF data is now invalid and should be removed.
    _image.RemovePropertyItem(274);
}

(The above code snippet is for the sake of simplicity "borrowed" directly from the user ReenignE on StackOverflow - The rest of the control is all my doing! Give credit where credit is due...)

History

Version 1.2 (2019-08-26)

  • New functionality: Added StartEditing property that determines when the editing should start
  • New functionality: Added StartEdit and EndEdit method calls
  • New functionality: Added methods to save directly to file, SaveCroppedImage (2 overloads)
  • New functionality: Added methods to save thumbnail directly to file, SaveCroppedImageThumbnail (2 overloads)
  • New functionality: Added ResetSelection method
  • Bugfix: MaintainAspectRatio mode didn't work properly

Version 1.1 (2019-08-22)

  • Bugfix - Image didn't resize with the control
  • Bugfix - Fixed "negative" selection rectangles
  • Bugfix - Fixed rounding errors for square image selections
  • Improvements - A few minor cosmetic code changes

Version 1.0 (2019-08-21)

  • Initial release

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