故事:用戶上傳將被添加到照片庫的圖像。作爲上傳過程的一部分,我們需要A)將圖像存儲在Web服務器的硬盤驅動器上,B)將圖像的縮略圖存儲在Web服務器的硬盤上。什麼是使用ASP.NET創建縮略圖的「最佳」方式?
「最佳」在這裏被定義爲
- 比較容易實現,理解和保持合理的質量縮略圖
- 結果
性能和高品質的縮略圖是次要的。
故事:用戶上傳將被添加到照片庫的圖像。作爲上傳過程的一部分,我們需要A)將圖像存儲在Web服務器的硬盤驅動器上,B)將圖像的縮略圖存儲在Web服務器的硬盤上。什麼是使用ASP.NET創建縮略圖的「最佳」方式?
「最佳」在這裏被定義爲
性能和高品質的縮略圖是次要的。
我想你最好的解決方案是使用.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);
}
}
以下是在VB.NET的圖像類別
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
對不起代碼標籤不喜歡vb.net碼的擴展方法。
「對不起,代碼標籤不喜歡vb.net代碼。」 =>我不怪它:P – 2010-10-15 03:05:59
你可以使用Image.GetThumbnailImage函數爲你做。
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);
}
GetThumbnailImage會的工作,但如果你想有一個好一點的質量可以爲Bitmap類指定圖像的選擇和將加載的圖像保存到那裏。下面是一些示例代碼:
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;
這提供了更好的質量比GetImageThumbnail會開箱
避免GetThumbnailImage - 它會提供非常不可預知的結果,因爲它試圖如果有使用嵌入式JPEG縮略圖 - 即使嵌入的縮略圖完全是錯誤的大小。 DrawImage()是一個更好的解決方案。
包裝你的位圖在使用{}子句 - 你不想泄露手柄四處飄蕩......
而且,你要設置你的JPEG編碼質量到90,這是在GDI +似乎閃耀最好的:
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);
從一對夫婦的其他地方使用上面還有一些例子,這裏是一個簡單的功能,剛剛降的(感謝瓊斯拿但業和其他人在這裏)。
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);
}
}
}
}
}
}
GetThumbnailImage僅適用於60x60或更小的縮略圖 - 它使用相機生成的縮略圖。還有[你需要處理的其他邊緣情況](http://nathanaeljones.com/163/20-image-resizing-pitfalls/),確保你知道他們....順便說一句, imageresizing.net](http://imageresizing.net)項目現在是免費的,開源的,並支持...並妥善處理29個陷阱。 – 2011-06-21 23:49:21