如何调整图像的大小 C#

Posted

技术标签:

【中文标题】如何调整图像的大小 C#【英文标题】:How to resize an Image C# 【发布时间】:2010-12-27 16:20:12 【问题描述】:

作为SizeWidthHeightGet()System.Drawing.Image 属性; 如何在 C# 运行时调整 Image 对象的大小?

现在,我正在创建一个新的Image,使用:

// objImage is the original Image
Bitmap objBitmap = new Bitmap(objImage, new Size(227, 171));

【问题讨论】:

不是正确的方法...使用低质量插值并可能导致原始流在新位图图像的持续时间内保持锁定...Read the image resizing pitfalls list 在进行自己的图像调整解决方案之前. 扔掉它!使用() 有效! 如果这些答案有帮助,请考虑标记已接受的答案。 不需要使用任何额外的库。 Mark 在下面发布的代码完美运行。 马克是谁?我没找到他的答案,但是有 3 个 cmets 指的是它。 【参考方案1】:

这将执行高质量的调整大小:

/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static Bitmap ResizeImage(Image image, int width, int height)

    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    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;

wrapMode.SetWrapMode(WrapMode.TileFlipXY) 防止图像边界周围出现重影——天真的调整大小会采样超出图像边界的透明像素,但通过镜像图像我们可以获得更好的样本(此设置非常明显) destImage.SetResolution 保持 DPI 不受物理尺寸的影响——在缩小图像尺寸或打印时可能会提高质量 合成控制像素与背景的混合方式——可能不需要,因为我们只绘制一件事。 graphics.CompositingMode 确定源图像中的像素是覆盖还是与背景像素组合。 SourceCopy 指定在渲染颜色时,它会覆盖背景颜色。 graphics.CompositingQuality 决定了分层图像的渲染质量水平。 graphics.InterpolationMode 确定如何计算两个端点之间的中间值 graphics.SmoothingMode 指定线条、曲线和填充区域的边缘是否使用平滑(也称为抗锯齿)——可能仅适用于矢量 graphics.PixelOffsetMode 影响绘制新图片时的渲染质量

保持纵横比留给读者作为练习(实际上,我只是不认为这个函数的工作是为你做这件事)。

另外,this is a good article 描述了图像调整大小的一些缺陷。上面的功能会覆盖大部分,不过你还是要操心saving。

【讨论】:

代码在调整图像大小时完美运行,但将大小从 66 KB 增加到 132 KB。锄头我可以减少它吗 @chamara 这可能是由于您选择的保存质量。见msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx试试质量=90 @kstubs 你肯定是。 Bitmap 本质上只是类的名称,您可以将其保存为您喜欢的任何文件类型。 @dotNetBlackBelt 您可能需要添加对System.Drawing 的引用并添加using System.Drawing.Imaging; 这不会保持原来的宽高比吧?【参考方案2】:

不确定这有什么困难,做你正在做的事情,使用重载的 Bitmap 构造函数来创建一个重新调整大小的图像,你唯一缺少的是转换回 Image 数据类型:

public static Image resizeImage(Image imgToResize, Size size)

    return (Image)(new Bitmap(imgToResize, size));


yourImage = resizeImage(yourImage, new Size(50,50));

【讨论】:

在将yourImage 分配给新图像之前,您不应该将其处理掉吗? 您可以手动处理它,也可以让垃圾收集器完成它的工作。没关系。 此代码无法控制非常重要的调整大小的质量。看看马克的答案。 @Elmue 垃圾收集器不会自动清理远程 GDI+ 对象。处理它们至关重要。 @Elmue 您所说的建议真的很糟糕。我已经在扫描软件、数百万文档和页面的批量转换以及 OCR 等方面从事成像工作 8 年了,除了在最微不足道的情况下不处理位图会造成内存泄漏、代码效率低下和软件将停止(崩溃,性能等)。当您不需要某些东西时,您应该始终尽快通知 GC,以便 GC 以后不必做太多工作,这会真正影响应用程序的性能和可伸缩性(在很大程度上)【参考方案3】:

在this question,你会有一些答案,包括我的:

public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
 
     Image imgPhoto = Image.FromFile(stPhotoPath); 

     int sourceWidth = imgPhoto.Width;
     int sourceHeight = imgPhoto.Height;

     //Consider vertical pics
    if (sourceWidth < sourceHeight)
    
        int buff = newWidth;

        newWidth = newHeight;
        newHeight = buff;
    

    int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
    float nPercent = 0, nPercentW = 0, nPercentH = 0;

    nPercentW = ((float)newWidth / (float)sourceWidth);
    nPercentH = ((float)newHeight / (float)sourceHeight);
    if (nPercentH < nPercentW)
    
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((newWidth -
                  (sourceWidth * nPercent)) / 2);
    
    else
    
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((newHeight -
                  (sourceHeight * nPercent)) / 2);
    

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);


    Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
                  PixelFormat.Format24bppRgb);

    bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                 imgPhoto.VerticalResolution);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Black);
    grPhoto.InterpolationMode =
        System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();
    imgPhoto.Dispose();
    return bmPhoto;

【讨论】:

你忘记了 imgPhoto.Dispose();该文件一直在使用中 这很有帮助,我正在我的应用程序中使用它。然而,重要的是要注意该算法不适用于透明图像。它将所有透明像素变为黑色。它可能很容易修复,但它只是给用户的一个注释。 :) 您不打算保存图像吗? imgPhoto.Save() ? @meme 您能否提供有关如何修复透明文档的黑色背景的链接。 我从背景颜色中得到很多边框出血。使用Math.CeilingdestWidthdestHeight 有所帮助,但还不够。但是,这种方法在 Azure 上的内存性能比其他解决方案要好得多。【参考方案4】:

为什么不使用System.Drawing.Image.GetThumbnailImage 方法?

public Image GetThumbnailImage(
    int thumbWidth, 
    int thumbHeight, 
    Image.GetThumbnailImageAbort callback, 
    IntPtr callbackData)

例子:

Image originalImage = System.Drawing.Image.FromStream(inputStream, true, true);
Image resizedImage = originalImage.GetThumbnailImage(newWidth, (newWidth * originalImage.Height) / originalWidth, null, IntPtr.Zero);
resizedImage.Save(imagePath, ImageFormat.Png);

来源: http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx

【讨论】:

这不是调整图像大小的正确方法。如果存在,这会从 jpg 中提取缩略图。如果它不存在,则您无法控制质量或新图像。此外,此代码原样存在内存泄漏。 @Bobrot 为什么会导致内存泄漏? GDI 库中的任何内容仍在非托管状态下运行。如果不使用 using 语句或事后处理对象,系统可能需要很长时间才能对这些对象进行垃圾收集并再次使内存可用。 正如你所说:可能需要很长时间。但这不是内存泄漏。如果内存永远不会被释放,那将是内存泄漏。但这是垃圾收集器的正常行为,它会在 CPU 空闲时释放内存。 using() 语句不能防止内存泄漏。它只是立即释放内存,而垃圾收集器在有时间时释放内存。这是此特定情况下的唯一区别。 查看图像调整大小的陷阱:nathanaeljones.com/blog/2009/20-image-resizing-pitfalls "使用 GetThumbnailImage()。GetThumbnailImage() 似乎是显而易见的选择,许多文章都推荐使用它。不幸的是,它总是抓取嵌入的 jpeg 缩略图(如果存在)。有些照片有这些,有些没有——这通常取决于您的相机。您会想知道为什么 GetThumbnailImage 在某些照片上效果很好,但在其他照片上却非常模糊。GetThumbnailImage() 对于大于 10 像素 x 10 像素的照片不可靠出于这个原因。”【参考方案5】:

您可以尝试net-vips,这是libvips 的C# 绑定。它是一个惰性、流式、需求驱动的图像处理库,因此无需加载整个图像即可完成此类操作。

例如,它带有一个方便的图像缩略图:

using Image image = Image.Thumbnail("image.jpg", 300, 300);
image.WriteToFile("my-thumbnail.jpg");

它还支持智能裁剪,这是一种智能地确定图像最重要部分并在裁剪图像时保持焦点的方式。例如:

using Image image = Image.Thumbnail("owl.jpg", 128, crop: Enums.Interesting.Attention);
image.WriteToFile("tn_owl.jpg");

其中owl.jpg 是偏心构图:

给出这个结果:

首先它缩小图像以使垂直轴为 128 像素,然后使用attention 策略将其裁剪为 128 像素。这个搜索图像以寻找可能引起人眼的特征,请参阅Smartcrop() 了解详情。

【讨论】:

您对 libvips 的绑定看起来很棒。我一定会看看你的库。感谢您将其提供给 C# 开发人员! 这太棒了!我不知道图像处理库可以看起来这么好。 不错!比 ImageMagick 重 对不起,如果我的问题很愚蠢。我在“Image.Thumbnail”中的缩略图部分和 image.WriteToFile 的 WriteToFile 部分下得到一个红色下划线。请问我应该使用什么“使用...;我应该使用?我知道使用 NetVips;是其中之一。谢谢 @Gregbert using NetVips; 应该可以完成这项工作。您是否安装了 NuGet 包?如果这不起作用,请在 NetVips 问题跟踪器上打开一个新问题:github.com/kleisauke/net-vips/issues【参考方案6】:
public static Image resizeImage(Image image, int new_height, int new_width)

    Bitmap new_image = new Bitmap(new_width, new_height);
    Graphics g = Graphics.FromImage((Image)new_image );
    g.InterpolationMode = InterpolationMode.High;
    g.DrawImage(image, 0, 0, new_width, new_height);
    return new_image;

【讨论】:

您忘记处理图形了。似乎与new Bitmap(image, width, height) 相同的原理,具有更好的插值模式。我很好奇Default 是什么?比Low还差吗?【参考方案7】:

这将 -

无需循环即可调整宽度和高度 不超过图片的原始尺寸

/////////////

private void ResizeImage(Image img, double maxWidth, double maxHeight)

    double resizeWidth = img.Source.Width;
    double resizeHeight = img.Source.Height;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    
    if (resizeHeight > maxHeight)
    
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    

    img.Width = resizeWidth;
    img.Height = resizeHeight;

【讨论】:

OP 询问 System.Drawing.Image,您的代码将无法工作,因为 'Width' 和 'Height' 属性不可设置。但是,它适用于 System.Windows.Controls.Image。【参考方案8】:

此代码与上述答案之一发布的代码相同。但会将透明像素转换为白色而不是黑色...谢谢:)

    public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
    
        Image imgPhoto = Image.FromFile(stPhotoPath);

        int sourceWidth = imgPhoto.Width;
        int sourceHeight = imgPhoto.Height;

        //Consider vertical pics
        if (sourceWidth < sourceHeight)
        
            int buff = newWidth;

            newWidth = newHeight;
            newHeight = buff;
        

        int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
        float nPercent = 0, nPercentW = 0, nPercentH = 0;

        nPercentW = ((float)newWidth / (float)sourceWidth);
        nPercentH = ((float)newHeight / (float)sourceHeight);
        if (nPercentH < nPercentW)
        
            nPercent = nPercentH;
            destX = System.Convert.ToInt16((newWidth -
                      (sourceWidth * nPercent)) / 2);
        
        else
        
            nPercent = nPercentW;
            destY = System.Convert.ToInt16((newHeight -
                      (sourceHeight * nPercent)) / 2);
        

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);


        Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
                      PixelFormat.Format24bppRgb);

        bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                     imgPhoto.VerticalResolution);

        Graphics grPhoto = Graphics.FromImage(bmPhoto);
        grPhoto.Clear(Color.White);
        grPhoto.InterpolationMode =
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        grPhoto.DrawImage(imgPhoto,
            new Rectangle(destX, destY, destWidth, destHeight),
            new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
            GraphicsUnit.Pixel);

        grPhoto.Dispose();
        imgPhoto.Dispose();

        return bmPhoto;
    

【讨论】:

【参考方案9】:

这是我为特定要求编写的代码,即:目的地始终是横向比例。它应该会给你一个好的开始。

public Image ResizeImage(Image source, RectangleF destinationBounds)

    RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height);
    RectangleF scaleBounds = new RectangleF();

    Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height);
    Graphics graph = Graphics.FromImage(destinationImage);
    graph.InterpolationMode =
        System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

    // Fill with background color
    graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds);

    float resizeRatio, sourceRatio;
    float scaleWidth, scaleHeight;

    sourceRatio = (float)source.Width / (float)source.Height;

    if (sourceRatio >= 1.0f)
    
        //landscape
        resizeRatio = destinationBounds.Width / sourceBounds.Width;
        scaleWidth = destinationBounds.Width;
        scaleHeight = sourceBounds.Height * resizeRatio;
        float trimValue = destinationBounds.Height - scaleHeight;
        graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight);
    
    else
    
        //portrait
        resizeRatio = destinationBounds.Height/sourceBounds.Height;
        scaleWidth = sourceBounds.Width * resizeRatio;
        scaleHeight = destinationBounds.Height;
        float trimValue = destinationBounds.Width - scaleWidth;
        graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height);
    

    return destinationImage;


【讨论】:

太棒了!!!我在肖像图像中遇到了麻烦,在尝试了网络上寻求的许多解决方案之后,这是唯一完美的!非常感谢!【参考方案10】:

在我制作的应用程序中,有必要创建一个具有多个选项的函数。它很大,但它会调整图像大小,可以保持纵横比,并且可以切割边缘以仅返回图像的中心:

/// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <param name="getCenter">return the center bit of the image</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio, Boolean getCenter)
    
        int newheigth = heigth;
        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFileLocation);

        // Prevent using images internal thumbnail
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

        if (keepAspectRatio || getCenter)
        
            int bmpY = 0;
            double resize = (double)FullsizeImage.Width / (double)width;//get the resize vector
            if (getCenter)
            
                bmpY = (int)((FullsizeImage.Height - (heigth * resize)) / 2);// gives the Y value of the part that will be cut off, to show only the part in the center
                Rectangle section = new Rectangle(new Point(0, bmpY), new Size(FullsizeImage.Width, (int)(heigth * resize)));// create the section to cut of the original image
                //System.Console.WriteLine("the section that will be cut off: " + section.Size.ToString() + " the Y value is minimized by: " + bmpY);
                Bitmap orImg = new Bitmap((Bitmap)FullsizeImage);//for the correct effect convert image to bitmap.
                FullsizeImage.Dispose();//clear the original image
                using (Bitmap tempImg = new Bitmap(section.Width, section.Height))
                
                    Graphics cutImg = Graphics.FromImage(tempImg);//              set the file to save the new image to.
                    cutImg.DrawImage(orImg, 0, 0, section, GraphicsUnit.Pixel);// cut the image and save it to tempImg
                    FullsizeImage = tempImg;//save the tempImg as FullsizeImage for resizing later
                    orImg.Dispose();
                    cutImg.Dispose();
                    return FullsizeImage.GetThumbnailImage(width, heigth, null, IntPtr.Zero);
                
            
            else newheigth = (int)(FullsizeImage.Height / resize);//  set the new heigth of the current image
        //return the image resized to the given heigth and width
        return FullsizeImage.GetThumbnailImage(width, newheigth, null, IntPtr.Zero);
    

为了更容易访问函数,可以添加一些重载函数:

/// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width)
    
        return resizeImageFromFile(OriginalFileLocation, heigth, width, false, false);
    

    /// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio)
    
        return resizeImageFromFile(OriginalFileLocation, heigth, width, keepAspectRatio, false);
    

现在是可选设置的最后两个布尔值。 像这样调用函数:

System.Drawing.Image ResizedImage = resizeImageFromFile(imageLocation, 800, 400, true, true);

【讨论】:

【参考方案11】:
public string CreateThumbnail(int maxWidth, int maxHeight, string path)


    var image = System.Drawing.Image.FromFile(path);
    var ratioX = (double)maxWidth / image.Width;
    var ratioY = (double)maxHeight / image.Height;
    var ratio = Math.Min(ratioX, ratioY);
    var newWidth = (int)(image.Width * ratio);
    var newHeight = (int)(image.Height * ratio);
    var newImage = new Bitmap(newWidth, newHeight);
    Graphics thumbGraph = Graphics.FromImage(newImage);

    thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
    thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
    //thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

    thumbGraph.DrawImage(image, 0, 0, newWidth, newHeight);
    image.Dispose();

    string fileRelativePath = "newsizeimages/" + maxWidth + Path.GetFileName(path);
    newImage.Save(Server.MapPath(fileRelativePath), newImage.RawFormat);
    return fileRelativePath;

点击这里http://bhupendrasinghsaini.blogspot.in/2014/07/resize-image-in-c.html

【讨论】:

【参考方案12】:

如果您使用的是BitmapSource

var resizedBitmap = new TransformedBitmap(
    bitmapSource,
    new ScaleTransform(scaleX, scaleY));

如果您想更好地控制质量,请先运行:

RenderOptions.SetBitmapScalingMode(
    bitmapSource,
    BitmapScalingMode.HighQuality);

(默认为BitmapScalingMode.Linear,相当于BitmapScalingMode.LowQuality。)

【讨论】:

【参考方案13】:

我使用 ImageProcessorCore,主要是因为它适用于 .Net Core。

而且它有更多的选项,例如转换类型、裁剪图像等等

http://imageprocessor.org/imageprocessor/

【讨论】:

我看了,这不支持 .NET Core。它是针对完整框架构建的。【参考方案14】:

您可以为此使用Accord.NET framework。它提供了几种不同的调整大小的方法:

Bicubic Bilinear Nearest Neighbour

【讨论】:

【参考方案15】:

注意:这不适用于 ASP.Net Core,因为 WebImage 依赖于 System.Web,但在以前版本的 ASP.Net 上,我多次使用这个 sn-p 并且很有用。

String ThumbfullPath = Path.GetFileNameWithoutExtension(file.FileName) + "80x80.jpg";
var ThumbfullPath2 = Path.Combine(ThumbfullPath, fileThumb);
using (MemoryStream stream = new MemoryStream(System.IO.File.ReadAllBytes(fullPath)))

      var thumbnail = new WebImage(stream).Resize(80, 80);
      thumbnail.Save(ThumbfullPath2, "jpg");

【讨论】:

【参考方案16】:

使用下面的函数和下面的例子来改变图像大小:

//Example : 
System.Net.Mime.MediaTypeNames.Image newImage = System.Net.Mime.MediaTypeNames.Image.FromFile("SampImag.jpg");
System.Net.Mime.MediaTypeNames.Image temImag = FormatImage(newImage, 100, 100);

//image size modification unction   
public static System.Net.Mime.MediaTypeNames.Image FormatImage(System.Net.Mime.MediaTypeNames.Image img, int outputWidth, int outputHeight)


    Bitmap outputImage = null;
    Graphics graphics = null;
    try
    
         outputImage = new Bitmap(outputWidth, outputHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
         graphics = Graphics.FromImage(outputImage);
         graphics.DrawImage(img, new Rectangle(0, 0, outputWidth, outputHeight),
         new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);

         return outputImage;
     
     catch (Exception ex)
     
           return img;
     

【讨论】:

请考虑在上面的答案中解释如何使用此代码,代码的作用以及它如何解决原始问题中的问题。 我也添加了用例。使用上面的函数和下面的例子。 Image newImage = Image.FromFile("SampImag.jpg"); Image temImag = FormatImage(newImage, 100, 100);【参考方案17】:

调整图像大小并保存图像以适应宽度和高度,就像画布保持图像比例一样

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace Infra.Files

    public static class GenerateThumb
    
        /// <summary>
        /// Resize and save an image to fit under width and height like a canvas keeping things proportional
        /// </summary>
        /// <param name="originalImagePath"></param>
        /// <param name="thumbImagePath"></param>
        /// <param name="newWidth"></param>
        /// <param name="newHeight"></param>
        public static void GenerateThumbImage(string originalImagePath, string thumbImagePath, int newWidth, int newHeight)
        
            Bitmap srcBmp = new Bitmap(originalImagePath);
            float ratio = 1;
            float minSize = Math.Min(newHeight, newHeight);

            if (srcBmp.Width > srcBmp.Height)
            
                ratio = minSize / (float)srcBmp.Width;
            
            else
            
                ratio = minSize / (float)srcBmp.Height;
            

            SizeF newSize = new SizeF(srcBmp.Width * ratio, srcBmp.Height * ratio);
            Bitmap target = new Bitmap((int)newSize.Width, (int)newSize.Height);

            using (Graphics graphics = Graphics.FromImage(target))
            
                graphics.CompositingQuality = CompositingQuality.HighSpeed;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);

                using (MemoryStream memoryStream = new MemoryStream())
                
                    target.Save(thumbImagePath);
                
            
        
    

【讨论】:

【参考方案18】:

下面的函数将返回新的大小来显示图像。这在这里可能没有帮助。但它会返回调整大小的显示矩形大小。

 public static  class ResizeImage

    /// <summary>
    /// Return new resized size to display the image
    /// </summary>
    /// <param name="srcrectanle">source rectangle of image or you can pass the bitmap and set the size accrodingly</param>
    /// <param name="initSize">initial size of the page to draw image</param>
    /// <returns></returns>
    public static SizeF getResizedRectangle(RectangleF srcrectanle, SizeF initSize)
    
        float sw = srcrectanle.Width;
        float sh = srcrectanle.Height;
        float dw = initSize.Width;
        float dh = initSize.Height;
        float finalHeight, finalWidth;
        float Sourceratio = sw / sh;

        if (Sourceratio >= 1)
        
            finalWidth = (int)dw;
            float ratio = sw / dw;
            finalHeight = (sh / ratio);
        
        else
        
            finalHeight = (int)dh;
            float ratio = sh / dh;
            finalWidth = (sw / ratio);
        
        return new SizeF(finalHeight, finalHeight);


    

【讨论】:

以上是关于如何调整图像的大小 C#的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 调整透明图像的大小

c# 在保持纵横比的同时将图像调整为不同的大小

水平调整 BMP 图像大小的问题 (C#)

C# 图像裁剪器 + 大小调整器

C#表单,调整表单大小后,图像无法超出原始表单大小

在 PictureBox Form C# 中调整大小时丢失图像质量