2011-07-21 37 views
1

我正在將webforms應用程序移至MVC3。具有諷刺意味的是,除了一件事外,一切都很酷 - 圖片由處理程序提供,特別是Microsoft Generated Image Handler。它工作得很好 - 平均而言,一張450kb的照片在大約20kb的時間內輸出。使用MVC3與Webforms庫呈現最小可能的圖像大小

實際photo on disk重417kb,所以我得到了很大的減少。

移到MVC3我想刪除處理程序並使用控制器操作。然而,我似乎無法在渲染圖像時實現同樣的文件尺寸縮小。我走過源代碼並且獲取了他們的image transform code的精確副本,但我只能達到230 kb,這比ms處理程序輸出的大小還要大 - 16kb。

您可以see an example of both the controller and the handler here

我已經經歷了處理程序源代碼,邊走邊看不到任何東西它是被進一步壓縮圖像。如果您檢查兩幅圖像,您可以看到不同之處 - 處理程序渲染的圖像不太清晰,看起來更有顆粒感,但仍然可以滿足我的需求。

任何人都可以在這裏給我任何指針嗎?是以某種方式使用輸出壓縮?還是我忽略了一些非常明顯的東西?

下面的代碼在我家的控制器用來呈現圖像,並且是在該處理程序使用Image Transform class的FitImage方法的精確副本...

public ActionResult MvcImage() 
    { 
     var file = Server.MapPath("~/Content/test.jpg"); 
     var img = System.Drawing.Image.FromFile(file); 
     var sizedImg = MsScale(img); 

     var newFile = Server.MapPath("~/App_Data/test.jpg"); 
     if (System.IO.File.Exists(newFile)) 
     { 
      System.IO.File.Delete(newFile); 
     } 
     sizedImg.Save(newFile); 
     return File(newFile, "image/jpeg"); 
    } 

private Image MsScale(Image img) 
    { 
     var scaled_height = 267; 
     var scaled_width = 400; 
     int resizeWidth = 400; 
     int resizeHeight = 267; 
     if (img.Height == 0) 
     { 
      resizeWidth = img.Width; 
      resizeHeight = scaled_height; 
     } 
     else if (img.Width == 0) 
     { 
      resizeWidth = scaled_width; 
      resizeHeight = img.Height; 
     } 
     else 
     { 
      if (((float)img.Width/(float)img.Width < img.Height/(float)img.Height)) 
      { 
       resizeWidth = img.Width; 
       resizeHeight = scaled_height; 
      } 
      else 
      { 
       resizeWidth = scaled_width; 
       resizeHeight = img.Height; 
      } 
     } 

     Bitmap newimage = new Bitmap(resizeWidth, resizeHeight); 
     Graphics gra = Graphics.FromImage(newimage); 
     SetupGraphics(gra); 
     gra.DrawImage(img, 0, 0, resizeWidth, resizeHeight); 
     return newimage; 
    } 

    private void SetupGraphics(Graphics graphics) 
    { 
     graphics.CompositingMode = CompositingMode.SourceCopy; 
     graphics.CompositingQuality = CompositingQuality.HighSpeed; 
     graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     graphics.SmoothingMode = SmoothingMode.HighSpeed; 
    } 

回答

1

如果不設置編碼器的質量,它默認使用100。由於JPEG等圖像格式的工作方式,您將無法通過使用100來減小尺寸。我有一個VB.net代碼示例,介紹如何設置您應該能夠適應的質量參數。

80L這裏是質量設置。 80仍然給你一個相當高品質的圖像,但在大幅減少規模超過100

  Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newImage) 
      graphic.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic 
      graphic.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality 
      graphic.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality 
      graphic.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality 
      graphic.DrawImage(sourceImage, 0, 0, width, height) 

      ' now encode and send the new image 
      ' This is the important part 

      Dim info() As Drawing.Imaging.ImageCodecInfo = Drawing.Imaging.ImageCodecInfo.GetImageEncoders() 
      Dim encoderParameters As New Drawing.Imaging.EncoderParameters(1) 

      encoderParameters.Param(0) = New Drawing.Imaging.EncoderParameter(Drawing.Imaging.Encoder.Quality, 80L) 
      ms = New System.IO.MemoryStream 
      newImage.Save(ms, info(1), encoderParameters) 

當您保存或以其他方式設置編碼器參數後寫的形象,它會輸出它使用JPEG編碼器(以這種情況下)設置爲質量80.這將讓你大小節省您正在尋找。

+0

完美!我欠你一杯啤酒:) – Baldy