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