2008-08-26 8 views
20

Story: Der Benutzer lädt ein Bild hoch, das einer Fotogalerie hinzugefügt wird. Als Teil des Upload-Prozesses müssen wir A) das Image auf der Festplatte des Web-Servers speichern und B) ein Thumbnail des Images auf der Festplatte des Web-Servers speichern.Was ist der "beste" Weg, um ein Thumbnail mit ASP.NET zu erstellen?

„Best“ ist hier definiert als

  • relativ einfach zu implementieren, zu verstehen und
  • Ergebnisse in einer Miniaturansicht von angemessener Qualität

Leistung und qualitativ hochwertige Miniaturen zu halten sind sekundäre .

Antwort

12

Ich nehme an, Ihre beste Lösung wäre die GetThumbnailImage aus der .NET Image Klasse.

// 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 ist nur für Miniaturbilder von 60x60 oder kleiner geeignet - es verwendet das von der Kamera erzeugte Miniaturbild. Es gibt auch [29 andere Randfälle, die Sie behandeln müssen] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/), stellen Sie sicher, dass Sie über sie wissen .... Übrigens, die [ imageresizing.net] (http://imageresizing.net) Projekt ist jetzt frei, Open-Source und unterstützt ... Und behandelt die 29 Fallstricke richtig. –

3

Hier ist eine Erweiterung Methode in VB.NET für die Image-Klasse

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 

leider der Code-Tag nicht vb.net Code nicht mag.

+1

"Entschuldigung, das Code-Tag mag den vb.net-Code nicht." => Ich gebe es nicht zu: P –

0

Sie können die Image.GetThumbnailImage Funktion verwenden, um es für Sie zu tun.

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 funktionieren würde, aber wenn Sie ein wenig bessere Qualität wollen, können Sie Ihr Bild Optionen für die Bitmap-Klasse angeben und Speichere dein geladenes Bild dort. Hier ist ein Beispielcode:

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; 

Diese bessere Qualität als GetImageThumbnail bietet würde aus dem Kasten heraus

0

Vermeiden GetThumbnailImage - es wird sehr unberechenbar Ergebnisse liefern, da es das eingebettete JPEG Thumbnail falls vorhanden zu verwenden versucht - auch wenn das eingebettete Thumbnail vollständig die falsche Größe hat. DrawImage() ist eine viel bessere Lösung.

Wickeln Sie Ihre Bitmap in einer mit {} Klausel - Sie müssen nicht durchgesickert Griffe wollen herum schwimmen ...

Auch Sie Ihre JPEG-Encoding-Qualität auf 90 gesetzt werden soll, das ist, wo GDI + scheint das beste zu glänzen:

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

ein Beispiel oben und einige von ein paar anderen Orten verwenden, hier ist eine einfache Funktion nur in Drop (dank Nathanael Jones und andere hier).

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