8

I want to scale images, but I don't want the image to look skewed.

The image has to be 115x115 (length x width).

The image can't be over 115 pixels high (length), but if needed, the width can be less than 115 but not more.

Is this tricky?

Juha Syrjälä
  • 33,425
  • 31
  • 131
  • 183
mrblah
  • 99,669
  • 140
  • 310
  • 420

4 Answers4

6

You need to preserve aspect ratio:

float scale = 0.0;

    if (newWidth > maxWidth || newHeight > maxHeight)
    {
        if (maxWidth/newWidth < maxHeight/newHeight)
        {
            scale = maxWidth/newWidth;
        }
        else
        {
            scale = maxHeight/newHeight;
        }
        newWidth = newWidth*scale;
        newHeight = newHeight*scale;

    }

In the code, Initially newWidth/newHeight are width/Height of image.

Brij
  • 6,086
  • 9
  • 41
  • 69
  • If newHeight or newWidth is an integer it won't work properly, you will need a cast to `float`. – BrunoLM Nov 04 '10 at 10:44
4

Based on Brij's answer I made this extension method:

/// <summary>
/// Resize image to max dimensions
/// </summary>
/// <param name="img">Current Image</param>
/// <param name="maxWidth">Max width</param>
/// <param name="maxHeight">Max height</param>
/// <returns>Scaled image</returns>
public static Image Scale(this Image img, int maxWidth, int maxHeight)
{
    double scale = 1;

    if (img.Width > maxWidth || img.Height > maxHeight)
    {
        double scaleW, scaleH;

        scaleW = maxWidth / (double)img.Width;
        scaleH = maxHeight / (double)img.Height;

        scale = scaleW < scaleH ? scaleW : scaleH;
    }

    return img.Resize((int)(img.Width * scale), (int)(img.Height * scale));
}

/// <summary>
/// Resize image to max dimensions
/// </summary>
/// <param name="img">Current Image</param>
/// <param name="maxDimensions">Max image size</param>
/// <returns>Scaled image</returns>
public static Image Scale(this Image img, Size maxDimensions)
{
    return img.Scale(maxDimensions.Width, maxDimensions.Height);
}

The resize method:

/// <summary>
/// Resize the image to the given Size
/// </summary>
/// <param name="img">Current Image</param>
/// <param name="width">Width size</param>
/// <param name="height">Height size</param>
/// <returns>Resized Image</returns>
public static Image Resize(this Image img, int width, int height)
{
    return img.GetThumbnailImage(width, height, null, IntPtr.Zero);
}
BrunoLM
  • 97,872
  • 84
  • 296
  • 452
  • instead of img.Height, img.Source.Height worked for me (VS 2010 .net 4). in addition, Source was used for Width – mnemonic Jan 23 '13 at 19:47
2

You're looking to scale an image and preserve Aspect Ratio:

float MaxRatio = MaxWidth / (float) MaxHeight;
float ImgRatio = source.Width / (float) source.Height;

if (source.Width > MaxWidth)
return new Bitmap(source, new Size(MaxWidth, (int) Math.Round(MaxWidth /
ImgRatio, 0)));

if (source.Height > MaxHeight)
return new Bitmap(source, new Size((int) Math.Round(MaxWidth * ImgRatio,
0), MaxHeight));

return source;

Should help you, and if you're interested in the idea: Wikpedia article on Image Aspect Ratio

NGLN
  • 43,011
  • 8
  • 105
  • 200
Kristopher Ives
  • 5,838
  • 7
  • 42
  • 67
  • Having just tried this code (found it else where while searching for the same basic problem), it doesn't actually do the job if you start out with an image that has both width and height that are larger than the maximums - you need to apply either the first or second scaling depending on which dimension of the original image is greatest, otherwise you end up with one of the dimensions being larger than the maximum allowable in either of the scalings. –  Jan 15 '10 at 20:46
0

Take a look at Bertrands blog post about scaling images using GDI and WPF.

noocyte
  • 2,484
  • 5
  • 29
  • 44