<p>Story:  The user uploads an image that will be added to a photo gallery.  As part of the upload process, we need to A) store the image on the web server's hard drive and B) store a thumbnail of the image on the web server's hard drive.</p>

<p>"Best" here is defined as </p>

<ul>
<li>Relatively easy to implement, understand, and maintain</li>
<li>Results in a thumbnail of reasonable quality</li>
</ul>

<p>Performance and high-quality thumbnails are secondary.</p>

[{'answer_id': 27938, 'author': 'Huppie', 'author_id': 1830, 'author_profile': 'https://Stackoverflow.com/users/1830', 'pm_score': 5, 'selected': True, 'text': '<p>I suppose your best solution would be using the <a href="http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx" rel="noreferrer">GetThumbnailImage </a> from the .NET <a href="http://msdn.microsoft.com/en-us/library/system.drawing.image.aspx" rel="noreferrer">Image</a> class.</p>\n\n<pre><code>// Example in C#, should be quite alike in ASP.NET\n// Assuming filename as the uploaded file\nusing ( Image bigImage = new Bitmap( filename ) )\n{\n   // Algorithm simplified for purpose of example.\n   int height = bigImage.Height / 10;\n   int width = bigImage.Width / 10;\n\n   // Now create a thumbnail\n   using ( Image smallImage = image.GetThumbnailImage( width, \n                                                       height,\n                                                       new Image.GetThumbnailImageAbort(Abort), IntPtr.Zero) )\n   {\n      smallImage.Save("thumbnail.jpg", ImageFormat.Jpeg);\n   }\n}\n</code></pre>\n'}, {'answer_id': 27939, 'author': 'chrissie1', 'author_id': 2936, 'author_profile': 'https://Stackoverflow.com/users/2936', 'pm_score': 2, 'selected': False, 'text': '<p>Here is an extension method in VB.NET for the Image Class</p>\n\n<pre class="lang-vb prettyprint-override"><code>Imports System.Runtime.CompilerServices\n\nNamespace Extensions\n   \'\'\' &lt;summary&gt;\n   \'\'\' Extensions for the Image class.\n   \'\'\' &lt;/summary&gt;\n   \'\'\' &lt;remarks&gt;Several usefull extensions for the image class.&lt;/remarks&gt;\n   Public Module ImageExtensions\n\n      \'\'\' &lt;summary&gt;\n      \'\'\' Extends the image class so that it is easier to get a thumbnail from an image\n      \'\'\' &lt;/summary&gt;\n      \'\'\' &lt;param name="Input"&gt;Th image that is inputted, not really a parameter&lt;/param&gt;\n      \'\'\' &lt;param name="MaximumSize"&gt;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. &lt;/param&gt;\n      \'\'\' &lt;param name="KeepAspectRatio"&gt;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.&lt;/param&gt;\n      \'\'\' &lt;returns&gt;A thumbnail as image.&lt;/returns&gt;\n      \'\'\' &lt;remarks&gt;\n      \'\'\' &lt;example&gt;Can be used as such. \n      \'\'\' &lt;code&gt;\n      \'\'\' Dim _NewImage as Image \n      \'\'\' Dim _Graphics As Graphics\n      \'\'\' _Image = New Bitmap(100, 100)\n      \'\'\' _Graphics = Graphics.FromImage(_Image)\n      \'\'\' _Graphics.FillRectangle(Brushes.Blue, New Rectangle(0, 0, 100, 100))\n      \'\'\' _Graphics.DrawLine(Pens.Black, 10, 0, 10, 100)\n      \'\'\' Assert.IsNotNull(_Image)\n      \'\'\' _NewImage = _Image.ToThumbnail(10)\n      \'\'\' &lt;/code&gt;\n      \'\'\' &lt;/example&gt;\n      \'\'\' &lt;/remarks&gt;\n      &lt;Extension()&gt; _\n      Public Function ToThumbnail(ByVal Input As Image, ByVal MaximumSize As Integer, Optional ByVal KeepAspectRatio As Boolean = True) As Image\n         Dim ReturnImage As Image\n         Dim _Callback As Image.GetThumbnailImageAbort = Nothing\n         Dim _OriginalHeight As Double\n         Dim _OriginalWidth As Double\n         Dim _NewHeight As Double\n         Dim _NewWidth As Double\n         Dim _NormalImage As Image\n         Dim _Graphics As Graphics\n\n         _NormalImage = New Bitmap(Input.Width, Input.Height)\n         _Graphics = Graphics.FromImage(_NormalImage)\n         _Graphics.DrawImage(Input, 0, 0, Input.Width, Input.Height)\n         _OriginalHeight = _NormalImage.Height\n         _OriginalWidth = _NormalImage.Width\n         If KeepAspectRatio = True Then\n            If _OriginalHeight &gt; _OriginalWidth Then\n               If _OriginalHeight &gt; MaximumSize Then\n                  _NewHeight = MaximumSize\n                  _NewWidth = _OriginalWidth / _OriginalHeight * MaximumSize\n               Else\n                  _NewHeight = _OriginalHeight\n                  _NewWidth = _OriginalWidth\n               End If\n            Else\n               If _OriginalWidth &gt; MaximumSize Then\n                  _NewWidth = MaximumSize\n                  _NewHeight = _OriginalHeight / _OriginalWidth * MaximumSize\n               Else\n                  _NewHeight = _OriginalHeight\n                  _NewWidth = _OriginalWidth\n               End If\n            End If\n         Else\n            _NewHeight = MaximumSize\n            _NewWidth = MaximumSize\n         End If\n         ReturnImage = _\n            _NormalImage.GetThumbnailImage(Convert.ToInt32(_NewWidth), Convert.ToInt32(_NewHeight), _Callback, _\n                                    IntPtr.Zero)\n         _NormalImage.Dispose()\n         _NormalImage = Nothing\n         _Graphics.Dispose()\n         _Graphics = Nothing\n         _Callback = Nothing\n         Return ReturnImage\n      End Function\n   End Module\nEnd Namespace\n</code></pre>\n\n<p>Sorry the code tag doesn\'t like vb.net code.</p>\n'}, {'answer_id': 27940, 'author': 'Mark Ingram', 'author_id': 986, 'author_profile': 'https://Stackoverflow.com/users/986', 'pm_score': 0, 'selected': False, 'text': '<p>You can use the Image.GetThumbnailImage function to do it for you.</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx</a> (.NET 3.5)</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage(VS.80).aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage(VS.80).aspx</a> (.NET 2.0)</p>\n\n<pre><code>public bool ThumbnailCallback()\n{\n  return false;\n}\n\npublic void Example_GetThumb(PaintEventArgs e)\n{\n  Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);\n  Bitmap myBitmap = new Bitmap("Climber.jpg");\n  Image myThumbnail = myBitmap.GetThumbnailImage(40, 40, myCallback, IntPtr.Zero);\n  e.Graphics.DrawImage(myThumbnail, 150, 75);\n}\n</code></pre>\n'}, {'answer_id': 27950, 'author': 'Sean Chambers', 'author_id': 2993, 'author_profile': 'https://Stackoverflow.com/users/2993', 'pm_score': 5, 'selected': False, 'text': '<p>GetThumbnailImage would work, but if you want a little better quality you can specify your image options for the BitMap class and save your loaded image into there. Here is some sample code:</p>\n\n<pre><code>Image photo; // your uploaded image\n\nBitmap bmp = new Bitmap(resizeToWidth, resizeToHeight);\ngraphic = Graphics.FromImage(bmp);\ngraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;\ngraphic.SmoothingMode = SmoothingMode.HighQuality;\ngraphic.PixelOffsetMode = PixelOffsetMode.HighQuality;\ngraphic.CompositingQuality = CompositingQuality.HighQuality;\ngraphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);\nimageToSave = bmp;\n</code></pre>\n\n<p>This provides better quality than GetImageThumbnail would out of the box</p>\n'}, {'answer_id': 266640, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<p>Avoid GetThumbnailImage - it will provide very unpredictable results, since it tries to use the embedded JPEG thumbnail if available - even if the embedded thumbnail is entirely the wrong size. DrawImage() is a much better solution.</p>\n\n<p>Wrap your bitmap in a using{} clause - you don't want leaked handles floating around...</p>\n\n<p>Also, you'll want to set your Jpeg encoding quality to 90, which is where GDI+ seems to shine the best:</p>\n\n<pre><code>System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();\nSystem.Drawing.Imaging.EncoderParameters encoderParameters;\nencoderParameters = new System.Drawing.Imaging.EncoderParameters(1);\nencoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);\n\nthumb.Save(ms, info[1], encoderParameters);\n</code></pre>\n"}, {'answer_id': 944282, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>Using an example above and some from a couple of other places, here is an easy function to just drop in (thanks to Nathanael Jones and others here). </p>\n\n<pre><code>using System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.IO;\n\npublic static void ResizeImage(string FileNameInput, string FileNameOutput, double ResizeHeight, double ResizeWidth, ImageFormat OutputFormat)\n{\n    using (System.Drawing.Image photo = new Bitmap(FileNameInput))\n    {\n        double aspectRatio = (double)photo.Width / photo.Height;\n        double boxRatio = ResizeWidth / ResizeHeight;\n        double scaleFactor = 0;\n\n        if (photo.Width &lt; ResizeWidth &amp;&amp; photo.Height &lt; ResizeHeight)\n        {\n            // keep the image the same size since it is already smaller than our max width/height\n            scaleFactor = 1.0;\n        }\n        else\n        {\n            if (boxRatio &gt; aspectRatio)\n                scaleFactor = ResizeHeight / photo.Height;\n            else\n                scaleFactor = ResizeWidth / photo.Width;\n        }\n\n        int newWidth = (int)(photo.Width * scaleFactor);\n        int newHeight = (int)(photo.Height * scaleFactor);\n\n        using (Bitmap bmp = new Bitmap(newWidth, newHeight))\n        {\n            using (Graphics g = Graphics.FromImage(bmp))\n            {\n                g.InterpolationMode = InterpolationMode.HighQualityBicubic;\n                g.SmoothingMode = SmoothingMode.HighQuality;\n                g.CompositingQuality = CompositingQuality.HighQuality;\n                g.PixelOffsetMode = PixelOffsetMode.HighQuality;\n\n                g.DrawImage(photo, 0, 0, newWidth, newHeight);\n\n                if (ImageFormat.Png.Equals(OutputFormat))\n                {\n                    bmp.Save(FileNameOutput, OutputFormat);\n                }\n                else if (ImageFormat.Jpeg.Equals(OutputFormat))\n                {\n                    ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();\n                    EncoderParameters encoderParameters;\n                    using (encoderParameters = new System.Drawing.Imaging.EncoderParameters(1))\n                    {\n                        // use jpeg info[1] and set quality to 90\n                        encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);\n                        bmp.Save(FileNameOutput, info[1], encoderParameters);\n                    }\n                }\n            }\n        }\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/27921', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/308/']