Was ist der „beste“ Weg, mit ASP.NET ein Miniaturbild zu erstellen?[geschlossen]

StackOverflow https://stackoverflow.com/questions/27921

  •  09-06-2019
  •  | 
  •  

Frage

Geschichte:Der Benutzer lädt ein Bild hoch, das einer Fotogalerie hinzugefügt wird.Als Teil des Upload-Vorgangs müssen wir A) das Bild auf der Festplatte des Webservers speichern und B) eine Miniaturansicht des Bildes auf der Festplatte des Webservers speichern.

„Am besten“ ist hier definiert als

  • Relativ einfach zu implementieren, zu verstehen und zu warten
  • Ergibt ein Miniaturbild von angemessener Qualität

Leistung und hochwertige Miniaturansichten sind zweitrangig.

War es hilfreich?

Lösung

Ich nehme an, Ihre beste Lösung wäre die Verwendung von GetThumbnailImage aus dem .NET Bild 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);
   }
}

Andere Tipps

GetThumbnailImage würde funktionieren, aber wenn Sie eine etwas bessere Qualität wünschen, können Sie Ihre Bildoptionen für die BitMap-Klasse angeben und Ihr geladenes Bild dort speichern.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;

Dies bietet eine bessere Qualität als GetImageThumbnail standardmäßig hätte

Anhand eines Beispiels oben und einiger anderer Orte finden Sie hier eine einfache Funktion, die Sie einfach vorbeischauen können (danke an 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);
                    }
                }
            }
        }
    }
}

Hier ist eine Erweiterungsmethode 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

Tut mir leid, dass der Code-Tag den vb.net-Code nicht mag.

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

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

Vermeiden Sie GetThumbnailImage – es liefert sehr unvorhersehbare Ergebnisse, da es versucht, das eingebettete JPEG-Miniaturbild zu verwenden, sofern verfügbar – selbst wenn das eingebettete Miniaturbild völlig die falsche Größe hat.DrawImage() ist eine viel bessere Lösung.

Wickeln Sie Ihre Bitmap in eine using{}-Klausel ein – Sie möchten nicht, dass durchgesickerte Handles herumschweben ...

Außerdem sollten Sie Ihre JPEG-Kodierungsqualität auf 90 einstellen, wo GDI+ am besten zu glänzen scheint:

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top