Browse DevX
Sign up for e-mail newsletters from DevX


Discover Enhanced Image Manipulation with GDI+ : Page 3

Is image processing in unmanaged C++ a thing of the past? See how GDI+ measures up by using this sample image manipulation tool.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Resizing and Saving Images
Resizing an image is fairly easy. First, retrieve the image from file:

Image mg = Image.FromFile(sImageName,true);

Create a new bitmap with the desired dimensions:

Size newSize = new Size(10,20); Bitmap bp = new Bitmap(newSize.Width,newSize.Height);

Next, obtain a graphics object from the new image:

Graphics g = Graphics.FromImage(bp);

To control the quality of the image, specify the smoothing, interpolation, and pixeloffset modes:

g.SmoothingMode =SmoothingMode.HighQuality; g.InterpolationMode =InterpolationMode.HighQualityBicubic; g.PixelOffsetMode =PixelOffsetMode.HighQuality;

Then, specify the dimensions of the new image:

Rectangle rect=new Rectangle(0,0,newSize.Width,newSize.Height); Draw the old image on to the new image using the graphics object: g.DrawImage(mg,rect,0,0,mg.Width,mg.Height,GraphicsUnit.Pixel);

The image's new dimensions are contained in a bitmap object (bp), which is stored in memory. At this point, you can copy the metadata from the old image into the new image:

foreach (PropertyItem pItem in mg.PropertyItems) { bp.SetPropertyItem(pItem); }

The method I used to save all image types apart from JPEG is:


For jpeg images, I used another overloaded method of save, which allows for control over various properties of the new image, such as color depth and compression ratio. This method uses the ImageCodeInfo, Encoder, and EncoderParameter classes.

First, identify an image codec for the jpeg image. Use the ImageCodecInfo class (from System.Drawing.Image) to do this:

ImageCodecInfo[] codecs=ImageCodecInfo.GetImageEncoders(); ImageCodecInfo codec = null; for (int i = 0; i<codecs.Length;i++) { if(codecs[i].MimeType.Equals(jpeg_mimetype)) codec = codecs[i]; }

Ideally, you want to retain a colour depth of 24bits per pixel for the new image, and maintain a quality level of 80 percent of the original image (80 percent compression). To achieve this, create an encoder parameter for quality and colour depth:

if (codec!=null) { Encoder encoderInstance=Encoder.Quality; EncoderParameters[] encoderParametersInstance=new EncoderParameters(2); EncoderParameter encoderParameterInstance=new EncoderParameter(encoderInstance, 80L); encoderParametersInstance.Param[0]=encoderParameterInstance; encoderInstance=Encoder.ColorDepth; encoderParameterInstance=new EncoderParameter(encoderInstance, 24L); encoderParametersInstance.Param[1]=encoderParameterInstance; }

Save the new image to the file using the image codec for jpeg files and an array of EncoderParameters:

bp.Save(ImagePath,codec,encoderParametersInstance); }

You use similar code when drawing the image to the form. The difference is that you do this in the onPaint event of the form, and obtain the graphics object, our drawing surface from the form. The sample application allows end users to perform some colour adjustment, using the ImageAttributes class. One of the overloaded versions of DrawImage takes a parameter of ImageAttributes class. Here's how to use an ImageAttributes class to scale the red colour component of an Image:

Create an ImageAttributes object: ImageAttributes attributes = new ImageAttributes(); Create a 5 by 5 identity matrix: Float[][] colourArray = getIdentityMatrix();

When you apply the identity matrix to the image, it will leave the image unchanged. To scale the red colour of the image by a factor of two, change the element of the identity matrix at row 0 and column 0 to 2:

colourArray[0][0]=2f; Use this matrix to create a ColorMatrix object: ColorMatrix matrix = new ColorMatrix(colourArray); Pass this ColorMatrix object to the ImageAttribute object we created earlier: attributes.SetColorMatrix(matrix,ColorMatrixFlag.Default,ColorAdjustType.Bitmap); Specify smoothing mode, interpolation mode and PixelOffsetMode: e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; Now go ahead and draw the image: e.Graphics.DrawImage(mg,rect,0,0,mg.Width,mg.Height, GraphicsUnit.Pixel,attributes);

I hope this sample application has wet your appetite. There is a lot more in the GDI+ classes than what could be covered here. Go ahead and explore!

Tade Oyebode holds an MSc in Computing and recently completed an MSc in Finance at Birkbeck College, University of London, and has written several articles for Devx. He lives in London, United Kingdom with his wife Kemi, where he works at JPMorganChase. Reach him by e-mail at tade.oyebode@btinternet.com.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date