ストーリー: ユーザーは、フォト ギャラリーに追加される画像をアップロードします。アップロード プロセスの一環として、A) Web サーバーのハード ドライブに画像を保存し、B) Web サーバーのハード ドライブに画像のサムネイルを保存する必要があります。
ここでの「最高」は次のように定義されます
- 実装、理解、保守が比較的簡単
- 妥当な品質のサムネイルになります
パフォーマンスと高品質のサムネイルは二の次です。
ストーリー: ユーザーは、フォト ギャラリーに追加される画像をアップロードします。アップロード プロセスの一環として、A) Web サーバーのハード ドライブに画像を保存し、B) Web サーバーのハード ドライブに画像のサムネイルを保存する必要があります。
ここでの「最高」は次のように定義されます
パフォーマンスと高品質のサムネイルは二の次です。
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をそのまま使用するよりも優れた品質が提供されます
最善の解決策は、.NETImageクラスのGetThumbnailImageを使用することだと思います。
// 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コードが好きではありません。
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 は避けてください。埋め込まれたサムネイルが完全に間違ったサイズであっても、可能な場合は埋め込まれた JPEG サムネイルを使用しようとするため、非常に予測不可能な結果が得られます。DrawImage() は、はるかに優れたソリューションです。
ビットマップを using{} 句でラップします - リークされたハンドルが浮かび上がるのは望ましくありません...
また、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);