Following this answer, I made the following code for resizing an image while keeping the aspect ratio correct:
private static Bitmap ResizeImage(Image image, int? width, int? height)
{
var dimensions = GetImageDimensions(image.Width, image.Height, width, height);
var destRect = new Rectangle(0, 0, dimensions.Item1, dimensions.Item2);
var destImage = new Bitmap(dimensions.Item1, dimensions.Item2);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
I made the below method for getting the dimensions corrrect:
public static Tuple<int, int> GetImageDimensions(int originalWidth, int originalHeight, int? width, int? height)
{
double widthRatio = (double)originalHeight / (double)originalWidth;
double heighthRatio = (double)originalWidth / (double)originalHeight;
int newWidth = originalWidth;
int newHeight = originalHeight;
if (width.HasValue && !height.HasValue && width.Value <= originalWidth)
{
newWidth = width.Value;
newHeight = (int)(width.Value * widthRatio);
}
else if (!width.HasValue && height.HasValue && height.Value <= originalHeight)
{
newHeight = height.Value;
newWidth = (int)(height.Value * heighthRatio);
}
return new Tuple<int, int>(newWidth, newHeight);
}
My problem: In case a user fills in both a new width and a new height, instead of resizing the image I want to crop it (starting from the center pixel of the original image). See this image:
If I have an image that was originally 1000x1000 pixels (red in the image), and I pass it to my method along with a new with and height (both 500), I want to return a cropped image (green in the image). However, no matter what parameter I change in the ResizeImage
method, I can't seem to crop the image. In the call to graphics.DrawImage
, I've tried changing all of the parameters, but I can't seem to get the result as described in the image above. What's going on?