Click here to Skip to main content
Licence CPOL
First Posted 29 Oct 2008
Views 28,800
Downloads 1,392
Bookmarked 75 times

An Easy to Use Image Resizing and Cropping Control

By | 31 Oct 2008 | Article
Allows users to load, resize, and crop an image in "real time" with the bloat and complexity of other programs

The Problem

You need to allow users of your desktop app (WinForms) to resize and/or crop large pictures from within your software, perhaps to allow them to upload professional headshots that need to be of a uniform size or type. Installing and/or instructing the user base on using third party software is not an option.

The Solution

Normally, I would never dream of creating yet another image editing program. However, I found myself in a position where, given the user base, it made sense to create a control that would quickly and easily let users crop out a head shot of a person taken with the average digital camera. The driving force behind this solution was to prevent people from uploading pictures that were too large, both in dimension and file size.

Features

  • Easy to use interface.
  • Image resizing done in "real time"; no guessing based on percentages.
  • Required image dimensions can be set at design or runtime. Ensures users will load images of the proper size.
  • Supports loading of and saving to BMP, JPG, GIF, PNG, and TIF files.
  • Initially resizes image to fit in workspace.

Using the Control

The control can be used out of the box by simply dropping it onto a form and docking it. To integrate it into your solution, simply add it to your form, subscribe to the WorkComplete event, and call GetEditedImage.

imageResizer1.WorkComplete += 
   new ImageResizer.WorkCompleteDelegate(imageResizer1_WorkComplete);

void imageResizer1_WorkComplete(object sender, bool complete)
{
    if (complete)
    {
        pictureBox1.Image = imageResizer1.GetEditedImage();
        // your processing here...
    }
    else // user cancelled
    {
        pictureBox1.Image = null;
    }

    imageResizer1.Reset();
    imageResizer1.Visible = false;
    pictureBox1.Visible = true;
}

Points of Interest

Normally, it is a pain to do custom drawing inside the Paint event of a form. However I "cheated" by using a GroupBox to track the dimensions of the workspace. The GroupBox is anchored so as the control is resized, my coordinates are tracked automatically, and I don't have to worry about drawing outside the boundary. Here is the Paint method for those that are interested:

private void ImageResizer_Paint(object sender, PaintEventArgs e)
{
    // Draws alternating shaded rectangles so user
    // can differentiate canvas from image.
    bool xGrayBox = true;
    int backgroundX = 0;
    while (backgroundX < grpImage.Width)
    {
        int backgroundY = 0;
        bool yGrayBox = xGrayBox;
        while (backgroundY < grpImage.Height)
        {
            int recWidth = (int)((backgroundX + 50 > grpImage.Width) ?
            grpImage.Width - backgroundX : 50);

            int recHeight = (int)((backgroundY + 50 > grpImage.Height) ?
            grpImage.Height - backgroundY : 50);

            e.Graphics.FillRectangle(((Brush)(yGrayBox ?
            Brushes.LightGray : Brushes.Gainsboro)),
            backgroundX, backgroundY, recWidth + 2, recHeight + 2);

            backgroundY += 50;
            yGrayBox = !yGrayBox;
        }
        backgroundX += 50;
        xGrayBox = !xGrayBox;
    }

    if (!SuspendRefresh && DrawnImage != null)
    {
        // if the image is too large, draw only visible portion
        // as dictated by the scrollbars, otherwise draw the whole image.
        if (DrawnImage.Width > grpImage.Width || 
            DrawnImage.Height > grpImage.Height)
        {
            int rectX = 0;
            if (hsbImage.Value > 0)
            {
                rectX = hsbImage.Value;
            }
            int rectY = 0;
            if (vsbImage.Value > 0)
            {
                rectY = vsbImage.Value;
            }
            e.Graphics.DrawImage(DrawnImage, 0, 0,
            new Rectangle( rectX, rectY, grpImage.Width, grpImage.Height),
            GraphicsUnit.Pixel);
        }
        else
        {
            e.Graphics.DrawImage(DrawnImage, 0, 0);
        }

        // Draw the crop rectangle with both yellow and black 
        // so it is easily visible no matter the image.
        if (chkCrop.Checked)
        {
            e.Graphics.DrawRectangle(Pens.Yellow, CropBoxX, 
            CropBoxY, (float)nudCropWidth.Value, (float)nudCropHeight.Value);

            e.Graphics.DrawRectangle(Pens.Black, CropBoxX - 1, CropBoxY - 1,
            (float)nudCropWidth.Value + 2, (float)nudCropHeight.Value + 2);
        }
    }
}

History

  • 29th October, 2008: Initial post
  • 31st October, 2008: Download files updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Josh Fischer

Software Developer (Senior)

United States United States

Member

CodeProject MVP 2010
CodeProject prize winner - Best C# article of December 2009



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalresize cropbox with mouse event PinmemberBabita Shivade20:35 15 Apr '09  
GeneralSet back ground color in non cropped area of image. PinmemberBabita Shivade1:55 15 Apr '09  
Generalwant to add circle in place of rectangle at the time of cropping. PinmemberBabita Shivade22:34 13 Apr '09  
GeneralRe: want to add circle in place of rectangle at the time of cropping. PinmemberJosh Fischer4:56 14 Apr '09  
GeneralSome nice ideas but implementation is wanting Pinmemberdhaag21:03 4 Jan '09  
GeneralHopefully it's a typo ;-) Pinmembergholbrook6:39 5 Nov '08  
GeneralRe: Hopefully it's a typo ;-) PinmemberJosh Fischer7:22 5 Nov '08  
GeneralThats a nice UI Pinmemberdefwebserver17:35 3 Nov '08  
GeneralNice work! Pinmembertptshepo1:49 30 Oct '08  
GeneralRe: Nice work! PinmemberStumproot3:54 4 Nov '08  
GeneralRe: Nice work! PinmemberJosh Fischer5:55 4 Nov '08  
GeneralRe: Nice work! Pinmemberniketrk18:12 20 Nov '08  
I agree. Though in market some ready-made controls are available. one such control that I have seen is http://www.futurefiesta.com/downloads.htm[^]
I like the idea that you have developed and provided/shared the code.
I haven't compare one-to-one features, but at first glance it seems that as it is professional product, more features are included there(obviously).
GeneralRe: Nice work! PinmemberJosh Fischer6:53 21 Nov '08  
GeneralUpload Application PinmemberHarshdeep Mehta (4700787)10:41 29 Oct '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120529.1 | Last Updated 31 Oct 2008
Article Copyright 2008 by Josh Fischer
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid