If you want to generate a thumbnail that's substantially larger than the embedded thumbnail,
GetThumbnailImage() is likely to produce a severely degraded image. For example, try
downloading Figure 1 (a large file, so I've linked to it rather than try to display it in flow) and running the following code, which resizes it to 655 x 480 pixels:
void ThumbnailResize(string str_file, Size new_size)
{
Image src_image = Image.FromFile(str_file);
Image dst_image = src_image.GetThumbnailImage(new_size.Width,
new_size.Height, null, System.IntPtr.Zero);
dst_image.Save("tn-" + str_file,
System.Drawing.Imaging.ImageFormat.Jpeg);
dst_image.Dispose();
src_image.Dispose();
}
ThumbnailResize("aikido.jpg", new Size(655, 480));
Open up the rescaled image, and you'll see something like
Figure 2. Compare this with the same image resized in Paint Shop Pro (see
Figure 3). The difference in quality is painfully apparent.

Figure 2. Resolution 421 Pixels per Inch.
|
|

Figure 3. Resolution 180 Pixels per Inch. |
| Editor's note: Because we display supporting figures as thumbnail images on article pages, what you see on this page is essentially a thumbnail of a thumbnail. Please click on the thumbnails shown and view the images as popups in order to see the actual effect as the author intends. |
Finer Control
Even when your source images don't contain embedded thumbnails, though, there are good reasons why you can do better than call
GetThumbnailImage() to do your resizing. For a start, GDI+ gives you considerable control over the way your image is resampled, so it makes sense to take advantage of this flexibility. Consider the following code:
void ImageResize(string str_file, Size new_size)
{
Image src_image = Image.FromFile(str_file);
Bitmap bitmap = new Bitmap(new_size.Width, new_size.Height,
src_image.PixelFormat);
Graphics new_g = Graphics.FromImage(bitmap);
new_g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
new_g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
new_g.DrawImage(src_image, 0, 0, bitmap.Width, bitmap.Height);
src_image.Dispose();
bitmap.Save("ir-" + str_file, System.Drawing.Imaging.ImageFormat.Jpeg);
bitmap.Dispose();
new_g.Dispose();
}
 | |
| Figure 4. Resolution 96 Pixels per Inch. |
Having used your initial image to create a Graphics surface, you are now free to configure the way that surface is rendered. You achieve this by setting a variety of flags that the renderer will inspect when it composes the final image. Because you're now working with the full image, any embedded thumbnails are conveniently overlooked. You can see the result in
Figure 4, a vast improvement on
Figure 2, and of a comparable quality with
Figure 3.
In my experience, the default Graphics surface settings have been sufficient for most applications, but if you do want to customize things, the table below gives a few options to customize the smoothing, interpolation, and pixel-offset algorithms used to produce your new image.
Table 1. Smoothing, Interpolation, and Pixel Offset Modes for System.Graphics
| Smoothing Mode
|
Interpolation Mode
|
Pixel Offset Mode
|
| AntiAlias
|
Bicubic
|
Default
|
| Default
|
Bilinear
|
Half
|
| HighQuality
|
Default
|
HighQuality
|
| HighSpeed
|
High
|
HighSpeed
|
| None
|
HighQualityBicubic
|
None
|
|
|
HighQualityBilinear
|
|
|
|
Low
|
|
|
|
NearestNeighbour
|
|