使用 C# System.Drawing 生成缩略图时居中裁剪图像
Posted
技术标签:
【中文标题】使用 C# System.Drawing 生成缩略图时居中裁剪图像【英文标题】:Center crop image while using C# System.Drawing to generate thumbnail 【发布时间】:2018-11-16 00:09:23 【问题描述】:我有一个场景,我使用 System.Drawing 通过将原始图像的大小调整为提供的大小(正在使用的大小)来生成缩略图。如果源图像是矩形,则生成的缩略图需要是方形的,而不会破坏图像(拉伸它)。到目前为止,我有以下代码:
//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
【问题讨论】:
【参考方案1】:我已经找到了解决方案,需要将 Graphics.DrawImage 用作可以与目标矩形一起提供计算偏移量的点,以创建完美的中心裁剪方形结果。以下是改进后的代码:
//Obtain original image from input stream
using (var sourceImage = new Bitmap(Image.FromStream(inStream)))
//Obtain source dimensions and initialize scaled dimensions and crop offsets
int sourceWidth = sourceImage.Width;
int sourceHeight = sourceImage.Height;
int scaledSourceWidth = 0;
int scaledSourceHeight = 0;
int offsetWidth = 0;
int offsetHeight = 0;
//Calculate cropping offset
if (sourceWidth > sourceHeight)
offsetWidth = (sourceWidth - sourceHeight) / 2;
scaledSourceWidth = sourceWidth / (sourceHeight / thumbSize);
scaledSourceHeight = thumbSize;
else if (sourceHeight > sourceWidth)
offsetHeight = (sourceHeight - sourceWidth) / 2;
scaledSourceHeight = sourceHeight / (sourceWidth / thumbSize);
scaledSourceWidth = thumbSize;
//Create new thumbnail image of height and width defined in thumbSize
Bitmap thumbnail = new Bitmap(thumbSize, thumbSize, PixelFormat.Format24bppRgb);
thumbnail.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
using (var graphics = Graphics.FromImage(thumbnail))
//Draw source image scaled down with aspect ratio maintained onto the thumbnail with the offset
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(sourceImage, new Rectangle(0, 0, scaledSourceWidth, scaledSourceHeight), offsetWidth, offsetHeight, sourceWidth, sourceHeight, GraphicsUnit.Pixel);
//Push thumbnail onto stream for upload
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
欢迎任何改进或优化。
【讨论】:
以上是关于使用 C# System.Drawing 生成缩略图时居中裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章
将 System.Drawing.Bitmap 缩放到给定大小,同时保持纵横比
在 C# 中,如何使用十六进制值创建 System.Drawing.Color 对象? [复制]