I have a scenario where I am generating a thumbnail using System.Drawing by resizing the original image to a provided size (size being used ). If the source image is a rectangle, the resulting thumbnail needs to be square without ruining the image (stretch it). I have the following code so far:
//Obtain original image from input stream
using (var sourceImage = new Bitmap(Image.FromStream(inStream)))
{
//Setting thumbnail aspect ratio based on source image
int destWidth, destHeight;
if (sourceImage.Width > sourceImage.Height)
{
destWidth = providedSize;
destHeight = Convert.ToInt32(sourceImage.Height * providedSize/ (double)sourceImage.Width);
}
else
{
destWidth = Convert.ToInt32(sourceImage.Width * providedSize/ (double)sourceImage.Height);
destHeight = providedSize;
}
//Initialize thumbnail bitmap
var thumbnail = new Bitmap(destWidth, destHeight);
//Create thumbnail
using (var graphics = Graphics.FromImage(thumbnail))
{
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(sourceImage, 0, 0, destWidth, destHeight);
using (MemoryStream stream = new MemoryStream())
{
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, Convert.ToInt64(Environment.GetEnvironmentVariable("ThumbnailQuality")));
var codecInfo = ImageCodecInfo.GetImageDecoders().FirstOrDefault(c => c.FormatID == ImageFormat.Jpeg.Guid);
thumbnail.Save(stream, codecInfo, encoderParameters);
stream.Position = 0;
//Upload thumbnail
}
}
}
And I've figured out the solution, the Graphics.DrawImage needs to be used as the point where calculated offsets can be provided along with the destination rectangle to create a perfect center-cropped square result. The following is the improved code:
Any improvements or optimizations are welcomed.