2011-06-28 110 views
112

使用System.Drawing.Image使用MaxHeight和MaxWidth限制按比例调整图像大小

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

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

+0

@Sarawut Positwinyu - 但是,你想要什么宽高比? – Bibhu

+0

如果图像无法调整到高度和宽度的最大值和最小值并且高宽比保持不变,您希望发生什么? –

+0

@Bibhu有没有很多类型的宽高比?我不知道这一点。我只是想让图像比例与原始图像比例相似。 –

回答

270

是否这样?

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; 
} 
+7

@Alex很好的使用Math.Min(I总是忘记那个) –

+5

我建议你在Graphics对象上使用using语句,至少可以节省一些资源:) – Schalk

+0

我只是在考虑一个案例,我不确定它是否可能与乘以比例宽度或高度可能仍然大于最大宽度或最大高度。 –

4

工作溶液:

对于尺寸下然后在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); 

多个参考在http://net4attack.blogspot.com/

5

长得多的解决方案,但占下列情况下调整大小图像:

  1. 图像是否小于边界框?
  2. 图像和边框是否正方形?
  3. 是图像平方和边界框是不
  4. 是对图像比边界框
  5. 比边界框
  6. 图像更宽更宽更高比边界框的图像更高

    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; 
         } 
        } 
    } 
    
+1

我认为有几个拼写错误,你使用比率来计算调整大小的图像的新高度。 正确var nH = oH * r; 不正确:var nH = oW * r; – wloescher