C# 从中心裁剪图像

标签 c# .net image-processing thumbnails

我正在使用 .NET(4.5) MVC(4.0) C#(5.0) 开发应用程序。 我想从已有的图像生成图像缩略图。 现在的要求就像它应该从图像中心生成最大正方形部分的缩略图而不拉伸(stretch)整个图像,除非图像是正方形大小。

例如我的原始图像尺寸:578x700 我想为占位符大小生成缩略图:200x150、185x138、140x140、89x66、80x80、45x45、28x28

我已经创建了下面的代码,但没有得到确切的结果。 这是我生成缩略图的核心方法

    public string GenerateThumbnailFromImage(string imageFilePath, int thumbWidth, int thumbHeight)
    {
        try
        {
            //Check if file exist
            if (File.Exists(imageFilePath))
            {
                //bool preserveAspectRatio = true;
                string oldFilePath = imageFilePath;
                string folderPath = Path.GetDirectoryName(imageFilePath);
                string filename = Path.GetFileNameWithoutExtension(imageFilePath);

                //Rename file with thumbnail size
                filename = filename + "_" + thumbWidth.ToString() + Path.GetExtension(imageFilePath);
                imageFilePath = Path.Combine(folderPath, filename);


                using (Image image = Image.FromFile(oldFilePath))
                {
                    decimal originalWidth = image.Width;
                    decimal originalHeight = image.Height;
                    decimal requiredThumbWidth = thumbWidth;
                    decimal requiredThumbHeight = thumbHeight;
                    decimal startXPosition = 0;
                    decimal startYPosition = 0;
                    decimal screenWidth = originalWidth;
                    decimal screenHeight = originalHeight;
                    decimal ar = thumbWidth < thumbHeight 
                                     ? originalWidth / originalHeight
                                     : originalHeight / originalWidth;

                    //Define Starting Position for thumbnail generation
                    if (originalWidth > originalHeight)
                        startXPosition = (originalWidth - originalHeight) / 2;
                    else if (originalHeight > originalWidth)
                        startYPosition = (originalHeight - originalWidth) / 2;

                    if (thumbWidth>thumbHeight)
                    {
                        requiredThumbWidth = thumbWidth;
                        requiredThumbHeight = requiredThumbWidth*ar;
                    }
                    else if (thumbHeight>thumbWidth)
                    {
                        requiredThumbHeight = thumbHeight;
                        requiredThumbWidth = requiredThumbHeight*ar;
                    }
                    else
                    {
                        requiredThumbWidth = thumbWidth;
                        requiredThumbHeight = thumbWidth;
                    }

                    using (var bmp = new Bitmap((int)requiredThumbWidth, (int)requiredThumbHeight))
                    {
                        Graphics gr = Graphics.FromImage(bmp);
                        gr.SmoothingMode = SmoothingMode.HighQuality;
                        gr.CompositingQuality = CompositingQuality.HighQuality;
                        gr.InterpolationMode = InterpolationMode.High;
                        var rectDestination = new Rectangle(0, 0, (int)requiredThumbWidth, (int)requiredThumbHeight);

                        gr.DrawImage(image, rectDestination, (int)startXPosition, (int)startYPosition, (int)screenWidth, (int)screenHeight, GraphicsUnit.Pixel);
                        bmp.Save(imageFilePath);

                        return filename;
                    }
                }
            }
            return null;
        }
        catch (Exception ex)
        {
            GlobalUtil.HandleAndLogException(ex, this);
            throw ex;
        }
        finally
        {

        }
    }

最佳答案

您需要获得目标大小与实际大小的比率。缩放较短的边,直到它触及实际图像大小。从中心开始裁剪它并将其缩放到所需的大小。

代码如下:



 public static Image ResizeImage(Image imgToResize, Size destinationSize)
        {
            var originalWidth = imgToResize.Width;
            var originalHeight = imgToResize.Height;

            //how many units are there to make the original length
            var hRatio = (float)originalHeight/destinationSize.Height;
            var wRatio = (float)originalWidth/destinationSize.Width;

            //get the shorter side
            var ratio = Math.Min(hRatio, wRatio);

            var hScale = Convert.ToInt32(destinationSize.Height * ratio);
            var wScale = Convert.ToInt32(destinationSize.Width * ratio);

            //start cropping from the center
            var startX = (originalWidth - wScale)/2;
            var startY = (originalHeight - hScale)/2;

            //crop the image from the specified location and size
            var sourceRectangle = new Rectangle(startX, startY, wScale, hScale);

            //the future size of the image
            var bitmap = new Bitmap(destinationSize.Width, destinationSize.Height);

            //fill-in the whole bitmap
            var destinationRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

            //generate the new image
            using (var g = Graphics.FromImage(bitmap))
            {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(imgToResize, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
            }

            return bitmap;

        }


这样调用它:


var thumbImage = ImageHelper.ResizeImage(image, new Size(45, 45));
thumbImage.Save(thumbFullPath);

关于C# 从中心裁剪图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18014365/

相关文章:

matlab - Matlab中imagesc()的非均匀轴

arrays - 为什么像素值保持不变?

c# - AudioSource的Unity3D共享设置

c# - 使用 lock(typeof(string)) 的含义是什么

matlab - matlab中如何删除矩阵中的特定值

.net - Silverlight的TextWrapping中的拆分字符是什么?

.net - 为什么 Windows 10 需要按需安装 .NET 3.5?

c# - 如何在 JetBrains Rider 的同一个项目中创建 MVC 和 Web API 项目?

c# - ServiceStack 序列化 byte[]。如何在javascript中反序列化?

.net - C# lambda 分配和收集