2008-08-26 368 views
20

故事:用戶上傳將被添加到照片庫的圖像。作爲上傳過程的一部分,我們需要A)將圖像存儲在Web服務器的硬盤驅動器上,B)將圖像的縮略圖存儲在Web服務器的硬盤上。什麼是使用ASP.NET創建縮略圖的「最佳」方式?

「最佳」在這裏被定義爲

  • 比較容易實現,理解和保持合理的質量縮略圖
  • 結果

性能和高品質的縮略圖是次要的。

回答

12

我想你最好的解決方案是使用.NET Image類中的​​。

// Example in C#, should be quite alike in ASP.NET 
// Assuming filename as the uploaded file 
using (Image bigImage = new Bitmap(filename)) 
{ 
    // Algorithm simplified for purpose of example. 
    int height = bigImage.Height/10; 
    int width = bigImage.Width/10; 

    // Now create a thumbnail 
    using (Image smallImage = image.GetThumbnailImage(width, 
                 height, 
                 new Image.GetThumbnailImageAbort(Abort), IntPtr.Zero)) 
    { 
     smallImage.Save("thumbnail.jpg", ImageFormat.Jpeg); 
    } 
} 
+5

GetThumbnailImage僅適用於60x60或更小的縮略圖 - 它使用相機生成的縮略圖。還有[你需要處理的其他邊緣情況](http://nathanaeljones.com/163/20-image-resizing-pitfalls/),確保你知道他們....順便說一句, imageresizing.net](http://imageresizing.net)項目現在是免費的,開源的,並支持...並妥善處理29個陷阱。 – 2011-06-21 23:49:21

3

以下是在VB.NET的圖像類別

Imports System.Runtime.CompilerServices 

Namespace Extensions 
    ''' <summary> 
    ''' Extensions for the Image class. 
    ''' </summary> 
    ''' <remarks>Several usefull extensions for the image class.</remarks> 
    Public Module ImageExtensions 

     ''' <summary> 
     ''' Extends the image class so that it is easier to get a thumbnail from an image 
     ''' </summary> 
     ''' <param name="Input">Th image that is inputted, not really a parameter</param> 
     ''' <param name="MaximumSize">The maximumsize the thumbnail must be if keepaspectratio is set to true then the highest number of width or height is used and the other is calculated accordingly. </param> 
     ''' <param name="KeepAspectRatio">If set false width and height will be the same else the highest number of width or height is used and the other is calculated accordingly.</param> 
     ''' <returns>A thumbnail as image.</returns> 
     ''' <remarks> 
     ''' <example>Can be used as such. 
     ''' <code> 
     ''' Dim _NewImage as Image 
     ''' Dim _Graphics As Graphics 
     ''' _Image = New Bitmap(100, 100) 
     ''' _Graphics = Graphics.FromImage(_Image) 
     ''' _Graphics.FillRectangle(Brushes.Blue, New Rectangle(0, 0, 100, 100)) 
     ''' _Graphics.DrawLine(Pens.Black, 10, 0, 10, 100) 
     ''' Assert.IsNotNull(_Image) 
     ''' _NewImage = _Image.ToThumbnail(10) 
     ''' </code> 
     ''' </example> 
     ''' </remarks> 
     <Extension()> _ 
     Public Function ToThumbnail(ByVal Input As Image, ByVal MaximumSize As Integer, Optional ByVal KeepAspectRatio As Boolean = True) As Image 
     Dim ReturnImage As Image 
     Dim _Callback As Image.GetThumbnailImageAbort = Nothing 
     Dim _OriginalHeight As Double 
     Dim _OriginalWidth As Double 
     Dim _NewHeight As Double 
     Dim _NewWidth As Double 
     Dim _NormalImage As Image 
     Dim _Graphics As Graphics 

     _NormalImage = New Bitmap(Input.Width, Input.Height) 
     _Graphics = Graphics.FromImage(_NormalImage) 
     _Graphics.DrawImage(Input, 0, 0, Input.Width, Input.Height) 
     _OriginalHeight = _NormalImage.Height 
     _OriginalWidth = _NormalImage.Width 
     If KeepAspectRatio = True Then 
      If _OriginalHeight > _OriginalWidth Then 
       If _OriginalHeight > MaximumSize Then 
        _NewHeight = MaximumSize 
        _NewWidth = _OriginalWidth/_OriginalHeight * MaximumSize 
       Else 
        _NewHeight = _OriginalHeight 
        _NewWidth = _OriginalWidth 
       End If 
      Else 
       If _OriginalWidth > MaximumSize Then 
        _NewWidth = MaximumSize 
        _NewHeight = _OriginalHeight/_OriginalWidth * MaximumSize 
       Else 
        _NewHeight = _OriginalHeight 
        _NewWidth = _OriginalWidth 
       End If 
      End If 
     Else 
      _NewHeight = MaximumSize 
      _NewWidth = MaximumSize 
     End If 
     ReturnImage = _ 
      _NormalImage.GetThumbnailImage(Convert.ToInt32(_NewWidth), Convert.ToInt32(_NewHeight), _Callback, _ 
            IntPtr.Zero) 
     _NormalImage.Dispose() 
     _NormalImage = Nothing 
     _Graphics.Dispose() 
     _Graphics = Nothing 
     _Callback = Nothing 
     Return ReturnImage 
     End Function 
    End Module 
End Namespace 

對不起代碼標籤不喜歡vb.net碼的擴展方法。

+1

「對不起,代碼標籤不喜歡vb.net代碼。」 =>我不怪它:P – 2010-10-15 03:05:59

0

你可以使用Image.GetThumbnailImage函數爲你做。

http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx(.NET 3.5)

http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage(VS.80).aspx(.NET 2.0)

public bool ThumbnailCallback() 
{ 
    return false; 
} 

public void Example_GetThumb(PaintEventArgs e) 
{ 
    Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback); 
    Bitmap myBitmap = new Bitmap("Climber.jpg"); 
    Image myThumbnail = myBitmap.GetThumbnailImage(40, 40, myCallback, IntPtr.Zero); 
    e.Graphics.DrawImage(myThumbnail, 150, 75); 
} 
34

GetThumbnailImage會的工作,但如果你想有一個好一點的質量可以爲Bitmap類指定圖像的選擇和將加載的圖像保存到那裏。下面是一些示例代碼:

Image photo; // your uploaded image 

Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight); 
graphic = Graphics.FromImage(bmp); 
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; 
graphic.SmoothingMode = SmoothingMode.HighQuality; 
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality; 
graphic.CompositingQuality = CompositingQuality.HighQuality; 
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight); 
imageToSave = bmp; 

這提供了更好的質量比GetImageThumbnail會開箱

0

避免GetThumbnailImage - 它會提供非常不可預知的結果,因爲它試圖如果有使用嵌入式JPEG縮略圖 - 即使嵌入的縮略圖完全是錯誤的大小。 DrawImage()是一個更好的解決方案。

包裝你的位圖在使用{}子句 - 你不想泄露手柄四處飄蕩......

而且,你要設置你的JPEG編碼質量到90,這是在GDI +似乎閃耀最好的:

System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); 
System.Drawing.Imaging.EncoderParameters encoderParameters; 
encoderParameters = new System.Drawing.Imaging.EncoderParameters(1); 
encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); 

thumb.Save(ms, info[1], encoderParameters); 
6

從一對夫婦的其他地方使用上面還有一些例子,這裏是一個簡單的功能,剛剛降的(感謝瓊斯拿但業和其他人在這裏)。

using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.IO; 

public static void ResizeImage(string FileNameInput, string FileNameOutput, double ResizeHeight, double ResizeWidth, ImageFormat OutputFormat) 
{ 
    using (System.Drawing.Image photo = new Bitmap(FileNameInput)) 
    { 
     double aspectRatio = (double)photo.Width/photo.Height; 
     double boxRatio = ResizeWidth/ResizeHeight; 
     double scaleFactor = 0; 

     if (photo.Width < ResizeWidth && photo.Height < ResizeHeight) 
     { 
      // keep the image the same size since it is already smaller than our max width/height 
      scaleFactor = 1.0; 
     } 
     else 
     { 
      if (boxRatio > aspectRatio) 
       scaleFactor = ResizeHeight/photo.Height; 
      else 
       scaleFactor = ResizeWidth/photo.Width; 
     } 

     int newWidth = (int)(photo.Width * scaleFactor); 
     int newHeight = (int)(photo.Height * scaleFactor); 

     using (Bitmap bmp = new Bitmap(newWidth, newHeight)) 
     { 
      using (Graphics g = Graphics.FromImage(bmp)) 
      { 
       g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
       g.SmoothingMode = SmoothingMode.HighQuality; 
       g.CompositingQuality = CompositingQuality.HighQuality; 
       g.PixelOffsetMode = PixelOffsetMode.HighQuality; 

       g.DrawImage(photo, 0, 0, newWidth, newHeight); 

       if (ImageFormat.Png.Equals(OutputFormat)) 
       { 
        bmp.Save(FileNameOutput, OutputFormat); 
       } 
       else if (ImageFormat.Jpeg.Equals(OutputFormat)) 
       { 
        ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders(); 
        EncoderParameters encoderParameters; 
        using (encoderParameters = new System.Drawing.Imaging.EncoderParameters(1)) 
        { 
         // use jpeg info[1] and set quality to 90 
         encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); 
         bmp.Save(FileNameOutput, info[1], encoderParameters); 
        } 
       } 
      } 
     } 
    } 
} 
相關問題