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();
}
else
{
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)
{
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 (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);
}
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