2012-10-25 38 views
4

可能重複:
How can I get better results when shrinking an image圖像損失同時收縮的某些圖像與Graphics.DrawImage()

我試圖用下面的代碼以產生大小200×200像素的縮略圖。它適用於某些圖像,但不適用於其他圖像。當它不起作用時,縮略圖會以該尺寸生成,但只能看到部分圖像,另一部分是灰色的(就像您使用了灰色筆刷並在縮略圖的頂部塗抹了一樣)。失敗時我無法看到趨勢。例如,400像素x 400像素大小的JPEG圖像會失敗。如果我嘗試生成大小爲150px x 150px的縮略圖,則不會發生圖像丟失。 如果這有助於解決問題 - http://s11.postimage.org/sse5zhpqr/Drawing_8.jpg

欣賞你的時間。

public Bitmap GenerateThumbnail(Bitmap sourceBitmap, int thumbnailWidth, int thumbnailHeight) 
    { 
     Bitmap thumbnailBitmap = null; 

     decimal ratio; 
     int newWidth = 0; 
     int newHeight = 0; 

     // If the image is smaller than the requested thumbnail size just return it 
     if (sourceBitmap.Width < thumbnailWidth && 
      sourceBitmap.Height < thumbnailHeight) 
     { 
      newWidth = sourceBitmap.Width; 
      newHeight = sourceBitmap.Height; 
     } 
     else if (sourceBitmap.Width > sourceBitmap.Height) 
     { 
      ratio = (decimal)thumbnailWidth/sourceBitmap.Width; 
      newWidth = thumbnailWidth; 
      decimal tempDecimalHeight = sourceBitmap.Height * ratio; 
      newHeight = (int)tempDecimalHeight; 
     } 
     else 
     { 
      ratio = (decimal)thumbnailHeight/sourceBitmap.Height; 
      newHeight = thumbnailHeight; 
      decimal tempDecimalHeight = sourceBitmap.Width * ratio; 
      newWidth = (int)tempDecimalHeight; 
     } 

     thumbnailBitmap = new Bitmap(newWidth, newHeight); 

     Graphics g = Graphics.FromImage(thumbnailBitmap); 
     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
     g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; 

     g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight); 
     g.DrawImage(sourceBitmap, 0, 0, newWidth, newHeight); 
     g.Dispose(); 


     return thumbnailBitmap; 
    } 

更新:

我做了一些更多的分析,似乎這個問題是在保存縮略圖到SQL Server數據庫中varbinary列。我正在使用一個MemoryStream來做到這一點如下。如果我將它保存到磁盤,它看起來很好。這是我的數據庫縮略圖 - http://s12.postimage.org/a7j50vr8d/Generated_Thumbnail.jpg

using (MemoryStream thumbnailStream = new MemoryStream()) 
{    
      thumbnailBitmap.Save(thumbnailStream, System.Drawing.Imaging.ImageFormat.Jpeg);    
      return thumbnailStream.ToArray(); 

} 

更新 - 已解決此問題。問題是我用於varbinary列的NHibernate映射。我不得不將類型指定爲「BinaryBlob」,以確保沒有數據> 8KB的無提示截斷。

+1

我建議看看http://stackoverflow.com/questions/6170912/how-can-i-get-better-results-when-shrinking-an-image/6171145#6171145 –

+0

感謝您的迴應。我嘗試了相同結果的代碼。這裏是我想要處理的圖像 - http://s11.postimage.org/sse5zhpqr/Drawing_8.jpg – nipps

+0

http://stackoverflow.com/questions/1890605/ghost-borders-ringing-when-resizing-in- gdi將解決你意想不到的邊界問題。 –

回答

2

我明白,這可能應該是一個評論,而不是一個答案,但對於額外的格式我發佈爲答案。

下面是我用來縮小圖像的代碼,我從來沒有過這樣的問題:

private byte[] ResizeImage(System.Drawing.Image image, double scaleFactor) 
     { 
      //a holder for the result 
      int newWidth = (int)(image.Width * scaleFactor); 
      int newHeight = (int)(image.Height * scaleFactor); 

      Bitmap result = new Bitmap(newWidth, newHeight); 

      //use a graphics object to draw the resized image into the bitmap 
      using (Graphics graphics = Graphics.FromImage(result)) 
      { 
       //set the resize quality modes to high quality 
       graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
       graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
       graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
       //draw the image into the target bitmap 
       graphics.DrawImage(image, 0, 0, result.Width, result.Height); 
      } 

      //return the resulting bitmap 
      ImageConverter converter = new ImageConverter(); 
      return (byte[])converter.ConvertTo(result, typeof(byte[]));    
     } 

當然,我返回byte[]而不是Bitmap,我然後將其保存到數據庫。

唯一的區別我真的可以看到的是,實例化了我的結果Bitmap具有的高度和寬度,我給FillRectangle方法沒有呼叫,我不設置PixelOffsetMode。我也開始與Image而不是一個Bitmap

希望這可以幫助你以某種方式,但。