Dot-Net

在 ASP.NET 中生成圖像縮略圖?

  • May 5, 2011

在 .NET 中生成縮略圖的最快和更可靠的方法是什麼?我需要獲取任何圖像,將其壓縮為 JPEG 並調整其大小。

我見過幾個 GDI+ 的例子,一些非自由組件,我記得 WPF 有一些關於成像的好東西。GDI+ 已經很老了,但是 WPF 的東西可能對伺服器環境沒有好處。

這必須在完全信任執行的 ASP.NET MVC 應用程序中工作,如果可能,同步執行。

你會推薦什麼?

更新:

根據Mantorok 的回答,我已經制定了這個範例,但它仍然是 GDI+,如果我嘗試使用大圖像,它會崩潰:

public void GenerateThumbnail(String filename, Int32? desiredWidth, 
   Int32? desiredHeight, Int64 quality, Stream s)
{
   using (Image image = Image.FromFile(filename))
   {
       Int32 width=0, height=0;

       if ((!desiredHeight.HasValue && !desiredWidth.HasValue) ||
           (desiredHeight.HasValue && desiredWidth.HasValue))
           throw new ArgumentException(
               "You have to specify a desired width OR a desired height");

       if (desiredHeight.HasValue)
       {
           width = (desiredHeight.Value * image.Width) / image.Height;
           height = desiredHeight.Value;
       }
       else
       {
           height = (desiredWidth.Value * image.Height) / image.Width;
           width = desiredWidth.Value;
       }

       using (var newImage = new Bitmap(width, height))
       using (var graphics = Graphics.FromImage(newImage))
       using (EncoderParameter qualityParam = 
           new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 
               quality))
       using (EncoderParameters encoderParams = new EncoderParameters(1))
       {
           graphics.DrawImage(image, 0, 0, width, height);
           ImageCodecInfo jpegCodec = ImageCodecInfo.GetImageEncoders().
               Single(e => e.MimeType.Equals("image/jpeg", 
                   StringComparison.Ordinal));
           encoderParams.Param[0] = qualityParam;
           newImage.Save(s, jpegCodec, encoderParams);
       }
   }
}

對於密集的伺服器端程式碼,我建議您使用除 GDI+ 之外的其他技術,這些技術並非旨在逐塊處理圖像(以流式方式)。

您可以使用Windows 映像組件或 WPF 來完成此任務。這裡有一個很好的例子,說明如何以快速且更重要的可擴展方式做到這一點:

從 ASP.NET 調整圖像大小的最快方法。而且它(更多)受支持。

多年來,這對我來說很好:

public static void CreateThumbnail(string filename, int desiredWidth, int desiredHeight, string outFilename)
{
   using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename))
   {
       float widthRatio = (float)img.Width / (float)desiredWidth;
       float heightRatio = (float)img.Height / (float)desiredHeight;
       // Resize to the greatest ratio
       float ratio = heightRatio > widthRatio ? heightRatio : widthRatio;
       int newWidth = Convert.ToInt32(Math.Floor((float)img.Width / ratio));
       int newHeight = Convert.ToInt32(Math.Floor((float)img.Height / ratio));
       using (System.Drawing.Image thumb = img.GetThumbnailImage(newWidth, newHeight, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailImageAbortCallback), IntPtr.Zero))
       {
           thumb.Save(outFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
       }
   }
}

public static bool ThumbnailImageAbortCallback()
{
   return true;
}

引用自:https://stackoverflow.com/questions/5882307