GDI+ brings many possibilities for resizing images from Visual FoxPro9. In this short post, I'll show 3 techniques, that can be applied depending on your needs.
IMPORTANT:
All samples below use the GDIPlus-X library, a VFPX project on GitHub.
Here they are:
1 - THUMBNAIL
Using very few code we can resize any image:
** How To: RESIZE with Thumbnail Technique ** This code resizes an Image to size 60x60 ** Saves to a PNG file DO LOCFILE("System.App") && GdiPlusX project on Github 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...
I find especially "SmoothingMode.HighQuality" and "InterpolationMode.HighQualityBicubic" very interesting.
ReplyDeleteDo you also know how to sharpen an image ?