Dot-Net
在 ASP.NET 中生成圖像縮略圖?
在 .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 來完成此任務。這裡有一個很好的例子,說明如何以快速且更重要的可擴展方式做到這一點:
多年來,這對我來說很好:
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; }