asp.net image thumbnails

¿Cuál es la "mejor" forma de crear una miniatura usando ASP.NET?



image thumbnails (6)

Aquí hay un método de extensión en VB.NET para la clase de imagen

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

Lo siento, la etiqueta de código no le gusta el código de vb.net.

Historia: el usuario carga una imagen que se agregará a una galería de fotos. Como parte del proceso de carga, necesitamos A) almacenar la imagen en el disco duro del servidor web y B) almacenar una miniatura de la imagen en el disco duro del servidor web.

"Lo mejor" aquí se define como

  • Relativamente fácil de implementar, comprender y mantener
  • Resultados en una miniatura de calidad razonable

El rendimiento y las miniaturas de alta calidad son secundarias.


Evite GetThumbnailImage: proporcionará resultados muy impredecibles, ya que trata de usar la miniatura JPEG incorporada, si está disponible, incluso si la miniatura incrustada tiene el tamaño incorrecto. DrawImage () es una solución mucho mejor.

Envuelva su mapa de bits en una cláusula {} con uso: no quiere que las manijas filtradas floten ...

Además, querrás configurar la calidad de codificación Jpeg en 90, que es donde GDI + parece brillar mejor:

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

Sé que un gran porcentaje de mis clientes compra mi código de redimensionamiento de imagen para usarlo en la integración con sistemas de carga de imágenes. Debido a la buena documentación, muy pocos necesitan ayuda para modificar el código. Para aquellos que lo hacen, ofrezco personalización por una pequeña tarifa.


GetThumbnailImage funcionaría, pero si quieres un poco mejor calidad puedes especificar tus opciones de imagen para la clase BitMap y guardar tu imagen cargada allí. Aquí hay un código de muestra:

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;

Esto proporciona una mejor calidad que GetImageThumbnail fuera de la caja


Puede usar la función Image.GetThumbnailImage para hacerlo por usted.

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


Supongo que su mejor solución sería usar GetThumbnailImage de la clase .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); } }


Usando un ejemplo anterior y algunos de otros lugares, aquí hay una función fácil de mencionar (gracias a Nathanael Jones y otros aquí).

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