2008-08-26 213 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); 
        } 
       } 
      } 
     } 
    } 
} 
相关问题