KallDrexx
KallDrexx

Reputation: 27803

What is wrong with my cropping logic?

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

Upvotes: 1

Views: 211

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112324

You have to specify the target area, not the total area:

var newSize = new Size(desiredWidth, desiredHeight);
var targetArea = new Rectangle(new Point(0, 0), newSize);
var cropArea = new Rectangle(new Point(0, cropHeightOffset), newSize);  
...
cropper.DrawImage(bmp, targetArea, cropArea, GraphicsUnit.Pixel); 

Upvotes: 2

Related Questions