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

An Easy to Use Image Resizing and Cropping Control

0.00/5 (No votes)
31 Oct 2008 1  
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 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