23

ストーリー: ユーザーは、フォト ギャラリーに追加される画像をアップロードします。アップロード プロセスの一環として、A) Web サーバーのハード ドライブに画像を保存し、B) Web サーバーのハード ドライブに画像のサムネイルを保存する必要があります。

ここでの「最高」は次のように定義されます

  • 実装、理解、保守が比較的簡単
  • 妥当な品質のサムネイルになります

パフォーマンスと高品質のサムネイルは二の次です。

4

6 に答える 6

37

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をそのまま使用するよりも優れた品質が提供されます

于 2008-08-26T12:58:19.733 に答える
15

最善の解決策は、.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);
   }
}
于 2008-08-26T12:53:53.800 に答える
3

これは、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コードが好きではありません。

于 2008-08-26T12:54:31.707 に答える
0

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);
}
于 2008-08-26T12:54:38.447 に答える
0

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);
于 2008-11-05T20:57:53.443 に答える