2012-03-16

Resizing images with GdiPlusX

 

GDI+ brings many possibilities for resizing images. In this short post, I'll show 3 techniques, that can be applied depending on your needs.

 

IMPORTANT:

All samples below use the new GDIPlus-X library. Get the latest stable release from Codeplex:

http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX&title=GDIPlusX

 

Here they are:

 

1 - THUMBNAIL

Using very few code we can resize any image:

** How To: RESIZE with Thumbnail Technique
**
** The code resizes an Image to size 60x60
** Saves to a PNG file

DO LOCFILE("System.App")

WITH _SCREEN.System.Drawing

* Variables to store the new Image size
LOCAL lnWidth, lnHeight
STORE 60 TO lnWidth, lnHeight

* Load the original Image
LOCAL loSrcImage as xfcBitmap
loSrcImage = .Bitmap.New(GETPICT())

* Get the thumbnail with the desired size
LOCAL loThumbnail as xfcImage
loThumbnail = loSrcImage.GetThumbnailImage(lnWidth, lnHeight)

* Save the resized image as Png
loResized.Save("c:\Resized1.png", .Imaging.ImageFormat.Png)

ENDWITH
RETURN

 

But there is a problem, that some kinds of Images like JPEGS may store embedded thumbnails. The function "GetThumbnailImage" in a first moment searches at the image file if there already exists a thumbnail stored. If yes, GDI+ will scale this image to the desired dimensions, causing some huge distortions.

In my opinion, this technique is recommended to be used to resize to small images, not bigger than 72x72.

 

2 - BITMAP LOADING

This code is also really short.

** How To: RESIZE with Bitmap loading Technique
**
** The code resizes an Image to size 60x60
** Saves to a PNG file

DO LOCFILE("System.App")

WITH _SCREEN.System.Drawing

* Variables to store the new Image size
LOCAL lnWidth, lnHeight
STORE 60 TO lnWidth, lnHeight

* Load the original Image
LOCAL loSrcImage as xfcBitmap
loSrcImage = .Bitmap.New(GETPICT())

* Get the resized version of the image
LOCAL loResized as xfcBitmap
loResized = .Bitmap.New(loSrcImage, lnWidth, lnHeight)

* Save the resized image as Png
loResized.Save("c:\Resized2.png", .Imaging.ImageFormat.Png)

ENDWITH
RETURN

The Bitmap class provides many overloads, that you can see at

http://msdn2.microsoft.com/en-us/library/System.Drawing.Bitmap.Bitmap%28vs.80%29.aspx

. One of them permits to load from any GDI+ image object, and automagically resizes it to the desired dimensions. Very easy, but it uses some default GDI+ properties, and does NOT ensure to generate the best possible quality.

This option is recommended for almost all cases when you need to rescale an image to a smaller size than the original.

 

3 - CUSTOMIZED RESIZING

The code below is longer, but permits to have a considerable control over the way our image is resized.

** How To: RESIZE with Image Drawing Technique
**
** The code resizes an Image to size 60x60
** Saves to a PNG file

** GDI+ gives you considerable control over the way your image is resampled,
** so it makes sense to take advantage of this flexibility.
** This way, we can obtain the most satisfactory image quality

DO LOCFILE("System.App")

WITH _SCREEN.System.Drawing

* Variables to store the new Image size
LOCAL lnWidth, lnHeight
STORE 60 TO lnWidth, lnHeight

* Load the original Image
LOCAL loSrcImage as xfcBitmap
loSrcImage = .Bitmap.New(GETPICT())

* Create a New Image with the desired size
LOCAL loResized as xfcBitmap
loResized = .Bitmap.New(lnWidth, lnHeight, ;
   .Imaging.PixelFormat.Format32bppARGB)


* Set the image resolution to be the same as the original
loResized.SetResolution(loSrcImage.HorizontalResolution, ;
   loSrcImage.VerticalResolution)

* Obtain a Graphics object to get the rights to draw on it
LOCAL loGfx as xfcGraphics
loGfx = .Graphics.FromImage(loResized)

* Set some properties, to ensure to have a better quality of image
loGfx.SmoothingMode = .Drawing2D.SmoothingMode.HighQuality
loGfx.InterpolationMode = .Drawing2D.InterpolationMode.HighQualityBicubic

* Draw the source image on the new image at the desired dimensions
loGfx.DrawImage(loSrcImage, 0, 0, lnWIdth, lnHeight)

* Save the resized image as Png
loResized.Save("c:\Resized3.png", .Imaging.ImageFormat.Png)

ENDWITH
RETURN

 

In this code we are controlling the Image Resolution, the Interpolation Mode, and the Smoothing Mode of the scaled image.

According to Libor Tinka, "Interpolation refers to how data is interpolated between endpoints. In its simplest form, to interpolate is to estimate a missing value by taking an average of known values at neighboring points."

In general the bicubic interpolation is used when more accuracy that's why I chose to use this mode for this sample.

Because of all these settings, this is the better option for resizing images to a bigger size than the original.

 

Libor Tinka wrote a very interesting article on this subjects, and provides many code samples and images showing the results that can be obtained using different Interpolation modes. Strongly recommended !

http://www.codeproject.com/csharp/imgresizoutperfg...

1 comment:

  1. I find especially "SmoothingMode.HighQuality" and "InterpolationMode.HighQualityBicubic" very interesting.

    Do you also know how to sharpen an image ?

    ReplyDelete