terjetyl / Simple.ImageResizer

A simple c# image resizer with ScaleToFit and ScaleToFill using wpf libraries. Resizes to jpg, gif, png, tiff. Demosite is hosted at AppHarbor: http://imageresizer.apphb.com/
58 stars 27 forks source link

Resized image is taller than max height #5

Closed daveb84 closed 10 years ago

daveb84 commented 10 years ago

When I resize an image using scale to fit that is too tall, the height of the resized image is not shrunk accordingly.

I found this when resizing a 116 x 93 pixel image to fit 340 x 75:

// imageData = PNG image, 116 x 93
var resizer = new ImageResizer(imageData);
var data = resizer.Resize(340, 75, false, ImageEncoding.Png);

resizer.SaveToFile("c:\myfile.png")

Expected: image should be 75 px high. Actual: image is 93 px high.

Looking through the code, it looks like the source of the problem is not casting the widths/heights to double in the ImageResizer.ScaleToFit method. This causes the height ratio to be 1.0 rather than 1.24:

Fixed version:

private BitmapSource ScaleToFit(int width, int height)
{
    Contract.Requires(width > 0);
    Contract.Requires(height > 0);

    // FIX: Extra casts to (double) here:
    double heightRatio = (double)_orgBitMap.PixelHeight / (double)height;
    double widthRatio = (double)_orgBitMap.PixelWidth / (double)width;

    if (heightRatio > widthRatio)
    {
        return ResizeImageByHeight(_imageBytes, height);
    }

    return ResizeImageByWidth(_imageBytes, width);
}
terjetyl commented 10 years ago

This is actually by design. If resizeheight > originalheight or resizewidth > originalwidth no resize will take place as upscaling images usually dont give good results

daveb84 commented 10 years ago

But that's not what is happening here.

The resize height is 75 and the original height is 93. It should shrink the height to 75, but it doesn't - the resulting image is 93.

Its because the REAL height aspect ratio (1.24 in this example) gets rounded down to 1. Therefore, the heightRatio > widthRatio condition fails incorrectly and ResizeImageByWidth is called instead of ResizeImageByHeight.

I'm guessing height aspect ratios greater than 1.5 would be fine because the value of heightRatio would get rounded to 2, therefore resulting in ResizeByHeight being called correctly

terjetyl commented 10 years ago

I have removed the restriction on upscaling images and added a fix for calculating size for ScaleToFit. An updated NuGet package is now available.Could you check it out?

daveb84 commented 10 years ago

Works like a charm! Thanks dude.