I am trying to crop a portrait image into a specific landscape size by cropping from the middle, and I seem to be doing things wrong. Right now I have the following code:
// Check the orientation
if(original.Height > original.Width) {
var bmp = new Bitmap(original);
int cropHeightOffset = (desiredHeight - original.Height) / 2;
var totalArea = new Rectangle(new Point(0, 0),
new Size(original.Width, original.Height));
var cropArea = new Rectangle(new Point(0, cropHeightOffset),
new Size(desiredWidth, desiredHeight));
// Create new blank image of the desired size
var newBmp = new Bitmap(bmp, new Size(desiredWidth, desiredHeight));
// Crop image
var cropper = Graphics.FromImage(newBmp);
// Draw it
cropper.DrawImage(bmp, totalArea, cropArea, GraphicsUnit.Pixel);
// Save
original.Dispose();
newBmp.Save(imagePath, ImageFormat.Jpeg);
}
When this happens it essentially resizes the image (thus distorting it) instead of cropping it.
If I switch around the totalArea and cropArea in my cropper.DrawImage call then it crops from the bottom, but it loops the image around twice (but is still the correct size).
I’m utterly confused on how to do this properly.
Edit: Here are some examples of things I have tried. There’s something I’m not getting, I’m just not sure what.
Using Oliver’s code:
var targetArea = new Rectangle(new Point(0, 0), new Size(desiredWidth, desiredHeight));
var cropArea = new Rectangle(new Point(0, cropHeightOffset), new Size(desiredWidth, desiredHeight));
...
// Draw it
cropper.DrawImage(bmp, targetArea, cropArea, GraphicsUnit.Pixel);
gives me http://dl.dropbox.com/u/6753359/crop/7278482-2.jpeg
var targetArea = new Rectangle(new Point(0, 0), new Size(desiredWidth, desiredHeight));
var cropArea = new Rectangle(new Point(0, cropHeightOffset), new Size(original.Width, original.Height));
......
// Draw it
cropper.DrawImage(bmp, cropArea, targetArea, GraphicsUnit.Pixel);
gives me http://dl.dropbox.com/u/6753359/crop/7278482-1.jpeg
The original image is: http://dl.dropbox.com/u/6753359/crop/7278482%20orig.jpeg
You have to specify the target area, not the total area: