2008-08-26 7 views
20

История: Пользователь загружает изображение, которое будет добавлено в фотогалерею. В рамках процесса загрузки нам необходимо: A) сохранить изображение на жестком диске веб-сервера и B) сохранить миниатюру изображения на жестком диске веб-сервера.Что такое «лучший» способ создания миниатюр с помощью ASP.NET?

«Best» здесь определяется как

  • Относительно легко реализовать, понимать и поддерживать
  • Результаты в миниатюре разумного качества

производительности и высококачественные миниатюры являются вторичными ,

ответ

12

Я полагаю, что ваше лучшее решение будет использовать GetThumbnailImage из класса .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 подходит только для миниатюр 60х60 или меньше - он использует уменьшенное изображение, созданное камерой. Также есть [29 других случаев с краями, которые вам нужно обрабатывать] (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 будет работать, но если вы хотите немного лучшего качества вы можете указать параметры изображения для класса растровой и сохраните загруженное изображение. Вот некоторые примеры код:

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); 
        } 
       } 
      } 
     } 
    } 
}