使用C#System.Drawing生成缩略图时居中裁剪图像

时间:2018-06-06 10:29:23

标签: c# thumbnails system.drawing system.drawing.imaging

我有一个场景,我使用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 个答案:

答案 0 :(得分:0)

我已经找到了解决方案,需要将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
        }
    }
}

欢迎任何改进或优化。

相关问题