C# 使用MaxHeight和MaxWidth约束按比例调整图像大小

C# 使用MaxHeight和MaxWidth约束按比例调整图像大小,c#,.net,winforms,image-processing,gdi+,C#,.net,Winforms,Image Processing,Gdi+,使用System.Drawing.Image 如果图像宽度或高度超过最大值,则需要按比例调整其大小。 调整大小后,需要确保宽度或高度都不超过限制 宽度和高度将自动调整,直到不超过最大值和最小值(可能的最大尺寸),并保持比例。像这样吗 public static void Test() { using (var image = Image.FromFile(@"c:\logo.png")) using (var newImage = ScaleImage(image, 300, 4

使用
System.Drawing.Image

如果图像宽度或高度超过最大值,则需要按比例调整其大小。 调整大小后,需要确保宽度或高度都不超过限制

宽度和高度将自动调整,直到不超过最大值和最小值(可能的最大尺寸),并保持比例。

像这样吗

public static void Test()
{
    using (var image = Image.FromFile(@"c:\logo.png"))
    using (var newImage = ScaleImage(image, 300, 400))
    {
        newImage.Save(@"c:\test.png", ImageFormat.Png);
    }
}

public static Image ScaleImage(Image image, int maxWidth, int maxHeight)
{
    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);

    using (var graphics = Graphics.FromImage(newImage))
        graphics.DrawImage(image, 0, 0, newWidth, newHeight);

    return newImage;
}
工作解决方案:

用于调整大小小于100Kb的图像的大小

WriteableBitmap bitmap = new WriteableBitmap(140,140);
bitmap.SetSource(dlg.File.OpenRead());
image1.Source = bitmap;

Image img = new Image();
img.Source = bitmap;
WriteableBitmap i;

do
{
    ScaleTransform st = new ScaleTransform();
    st.ScaleX = 0.3;
    st.ScaleY = 0.3;
    i = new WriteableBitmap(img, st);
    img.Source = i;
} while (i.Pixels.Length / 1024 > 100);

更多参考,请参阅更长的解决方案,但要考虑以下情况:

  • 图像是否比边界框小
  • 图像和边界框是正方形的吗
  • 是图像的正方形,而边界框不是
  • 图像是否比边界框宽且高
  • 图像是否比边界框宽
  • 图像是否高于边界框

    private Image ResizePhoto(FileInfo sourceImage, int desiredWidth, int desiredHeight)
    {
        //throw error if bouning box is to small
        if (desiredWidth < 4 || desiredHeight < 4)
            throw new InvalidOperationException("Bounding Box of Resize Photo must be larger than 4X4 pixels.");            
        var original = Bitmap.FromFile(sourceImage.FullName);
    
        //store image widths in variable for easier use
        var oW = (decimal)original.Width;
        var oH = (decimal)original.Height;
        var dW = (decimal)desiredWidth;
        var dH = (decimal)desiredHeight;
    
        //check if image already fits
        if (oW < dW && oH < dH)
            return original; //image fits in bounding box, keep size (center with css) If we made it bigger it would stretch the image resulting in loss of quality.
    
        //check for double squares
        if (oW == oH && dW == dH)
        {
            //image and bounding box are square, no need to calculate aspects, just downsize it with the bounding box
            Bitmap square = new Bitmap(original, (int)dW, (int)dH);
            original.Dispose();
            return square;
        }
    
        //check original image is square
        if (oW == oH)
        {
            //image is square, bounding box isn't.  Get smallest side of bounding box and resize to a square of that center the image vertically and horizontally with Css there will be space on one side.
            int smallSide = (int)Math.Min(dW, dH);
            Bitmap square = new Bitmap(original, smallSide, smallSide);
            original.Dispose();
            return square;
        }
    
        //not dealing with squares, figure out resizing within aspect ratios            
        if (oW > dW && oH > dH) //image is wider and taller than bounding box
        {
            var r = Math.Min(dW, dH) / Math.Min(oW, oH); //two dimensions so figure out which bounding box dimension is the smallest and which original image dimension is the smallest, already know original image is larger than bounding box
            var nH = oH * r; //will downscale the original image by an aspect ratio to fit in the bounding box at the maximum size within aspect ratio.
            var nW = oW * r;
            var resized = new Bitmap(original, (int)nW, (int)nH);
            original.Dispose();
            return resized;
        }
        else
        {
            if (oW > dW) //image is wider than bounding box
            {
                var r = dW / oW; //one dimension (width) so calculate the aspect ratio between the bounding box width and original image width
                var nW = oW * r; //downscale image by r to fit in the bounding box...
                var nH = oH * r;
                var resized = new Bitmap(original, (int)nW, (int)nH);
                original.Dispose();
                return resized;
            }
            else
            {
                //original image is taller than bounding box
                var r = dH / oH;
                var nH = oH * r;
                var nW = oW * r;
                var resized = new Bitmap(original, (int)nW, (int)nH);
                original.Dispose();
                return resized;
            }
        }
    }
    
    private Image ResizePhoto(FileInfo sourceImage,int desireedwidth,int desireedheight)
    {
    //如果bouning box太小,则抛出错误
    如果(所需宽度<4 | |所需高度<4)
    抛出新的InvalidOperationException(“调整照片大小的边界框必须大于4X4像素”);
    var original=Bitmap.FromFile(sourceImage.FullName);
    //将图像宽度存储在变量中以便于使用
    var oW=(十进制)原始宽度;
    var oH=(十进制)原始高度;
    var dW=(十进制)所需宽度;
    var dH=(十进制)所需高度;
    //检查图像是否已经匹配
    如果(oWdW&&oH>dH)//图像比边界框宽且高
    {
    var r=Math.Min(dW,dH)/Math.Min(oW,oH);//两个维度,因此找出哪个边界框维度最小,哪个原始图像维度最小,已经知道原始图像比边界框大
    var nH=oH*r;//将按纵横比缩小原始图像的比例,使其以纵横比内的最大尺寸适合边界框。
    var nW=oW*r;
    var resized=新位图(原始,(int)nW,(int)nH);
    原始。处置();
    返回调整大小;
    }
    其他的
    {
    if(oW>dW)//图像比边界框宽
    {
    var r=dW/oW;//一维(宽度),因此计算边界框宽度和原始图像宽度之间的纵横比
    var nW=oW*r;//按r缩小图像以适应边界框。。。
    var nH=oH*r;
    var resized=新位图(原始,(int)nW,(int)nH);
    原始。处置();
    返回调整大小;
    }
    其他的
    {
    //原始图像比边界框高
    var r=dH/oH;
    var nH=oH*r;
    var nW=oW*r;
    var resized=新位图(原始,(int)nW,(int)nH);
    原始。处置();
    返回调整大小;
    }
    }
    }
    

  • @Sarawut-Winyu-但是你想要什么样的纵横比呢?如果一个图像不能被调整到高度和宽度的最大值和最小值,并且纵横比保持不变,你想怎么办?@Bibhu有很多类型的纵横比吗?我不知道。我只是希望图像比例尽可能与原始图像比例相似。@Sarawut-Winyu-有关纵横比的更多信息,请查看此wiki链接@Sarawut假设Winyu没有误用纵横比这个术语。或者如果你在@Alex nice use of Math.Min(我总是忘了这个),我建议你在图形对象上使用using语句,至少可以节省一些资源:)我只是在考虑一个案例,我不确定在乘以比率后,宽度或高度是否可能仍然大于最大宽度或最大高度。如果使用asp.net,请确保您使用的是System.Drawing.Image。@Smith-如果不需要保存图像,请不要运行Save方法。这正是我的ScaleImage方法所做的-返回图像而不保存它。我认为在使用比率计算调整大小的图像的新高度时,存在一些输入错误。正确的var nH=oH*r;不正确:var nH=oW*r;修正了,只是没有评论。