2011-06-28 137 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