Was ist der „beste“ Weg, mit ASP.NET ein Miniaturbild zu erstellen?[geschlossen]
-
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.
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);