Full Version: Image manipulation with GDI+ in C#
Dream.In.Code > Programming Tutorials > C# Tutorials
PsychoCoder
Today we will be talking about manipulating images with C#, using the native .Net Framework, no 3rd party controls whatsoever. Well isn't that one of the selling points of the Framework is that we can write our own components/controls? One thing that I have noticed throughout my career is that working with graphics scares many new and intermediate programmers, and I'm here to show that with the proper .Net Namespaces you can make working with images look like cake work.

We will be working exclusively with the System.Drawing Namespace, which gives us access to GDI+. To demonstrate what can be done with this Namespace I have created a small class file, called ImageUtilities, where I can crop an image, resize an image, write text watermarks on an image, all at run-time. Lets take a look at this class;

With all classes you need reference to the proper Namespaces, in this class we will use


csharp

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Web;
using System.Drawing.Imaging;
using System.IO;



This class has some property variables, 1 Global (Class Level) variable and 3 properties. First the variables & constants


csharp

/// <summary>
/// variable to hold the image's format type
/// </summary>
private ImageFormat _formatType = ImageFormat.Gif;

/// <summary>
/// mime text property variable
/// </summary>
private string _mimeText;

/// <summary>
/// PercentOfOroginal property variable
/// </summary>
private float _percent;

/// <summary>
/// name of the image we're working with
/// </summary>
private string _image;

/// <summary>
/// font to be used when writing text
/// </summary>
private const string IMAGE_FONT = "Comic Sanf-Serif";



Now for the object's properties:
  • MimeType: The MIME type of the current image
  • ImageName: Name of the image we're manipulating
  • PercentOfOriginal: What percent of the original will the new size be
Now for the property code


csharp

//// <summary>
/// property to hold the mime type of this file
/// </summary>
public string MimeText
{
get { return _mimeText; }
set { _mimeText = value; }
}

/// <summary>
/// name of the image we're manipulating
/// </summary>
public string ImageName
{
get { return _image; }
set { _image = value; }
}

/// <summary>
/// for resizing, what percent are we changing; 75 percent of original
/// </summary>
public float PercentOfOriginal
{
get { return _percent; }
set { _percent = value; }
}



Now we get to jump right into working with images, a kind of baptism by fire situation. Don't worry, you'll do fine. First order of operation is to write a watermark onto an image. I would like to send special thanks to Martyr2 for his solution of changing the opacity of the watermark text. The process of watermarking is a 2 part process in this class, first method creates the image and Graphics object, while the 2nd takes care of writing the watermark for you.

First we will look at part one of this functionality


csharp

/// <summary>
/// method for getting the display image and write the watermark on it
/// </summary>
/// <returns></returns>
private Image GetDisplayImage(Image img, HttpContext context)
{
//get image t be written on
Bitmap bmp = new Bitmap(img);

//create a graphics object from the image
Graphics gfx = Graphics.FromImage(bmp);

//set smooting mode
gfx.SmoothingMode = SmoothingMode.AntiAlias;

//Write your text.
writeWaterMark(gfx, 75, 25, new Font(IMAGE_FONT, 17, FontStyle.Bold, GraphicsUnit.Pixel), "Sample from AngelzDesigns.com");
writeWaterMark(gfx, 75, 125, new Font(IMAGE_FONT, 17, FontStyle.Bold, GraphicsUnit.Pixel), "Image is copyright protected " + System.DateTime.Now.Year);
//Save the new image to the current output stream.
bmp.Save(context.Response.OutputStream, this._formatType);

//Clean house.
gfx.Dispose();

//return the image
return bmp;

}



Now for writing the semi-transparent watermark


csharp

// Takes a graphics object, a font object for our text, and the text we want to write.
// Then writes it to the handle as a watermark
private void writeWaterMark(Graphics graphicsHandle, int x, int y, Font ourFont, String text)
{
StringFormat strFormatter = new StringFormat();
SolidBrush transBrush = new SolidBrush(Color.FromArgb(90, 133, 72, 77));

// Drawstring the transparent text to the Graphics context at x,y position.
graphicsHandle.DrawString(text,
ourFont,
transBrush,
new PointF(x, y),
strFormatter);

}



Next in our class is the ability to change the opacity at run-time. We will accomplish this by introducing you to the ColorMatrix Class and the ImageAttributes Class of the System.Drawing.Imaging Namespace. So now lets look at hoe we combine all these classes to change the opacity of an image


csharp

/// <summary>
/// method for changing the opacity of an image
/// </summary>
/// <param name="image">image to set opacity on</param>
/// <param name="opacity">percentage of opacity</param>
/// <returns></returns>
public Image SetImageOpacity(Image image, float opacity)
{
try
{
//create a Bitmap the size of the image provided
Bitmap bmp = new Bitmap(image.Width, image.Height);

//create a graphics object from the image
Graphics gfx = Graphics.FromImage(bmp);

//create a color matrix object
ColorMatrix matrix = new ColorMatrix();

//set the opacity
matrix.Matrix33 = opacity;

//create image attributes
ImageAttributes attributes = new ImageAttributes();

//set the color(opacity) of the image
attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

//now draw the image
gfx.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
gfx.Dispose();
return bmp;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}



Next on this gravy train through Image-Ville is a look at resizing an image at run-time. Here we will accept a percentage amount (Say the user wants to resize the image to 75% of the original, we would then pass 75 as the value). We will them retrieve the original dimensions of the image (width & height) and multiply both by the percentage (.75 in our example) to get a height/width combinations that in proportion to the original


csharp

/// <summary>
/// method for resizing an image
/// </summary>
/// <param name="img">the image to resize</param>
/// <param name="percentage">Percentage of change (i.e for 105% of the original provide 105)</param>
/// <returns></returns>
public Image Resize(Image img, HttpContext context)
{
try
{
//get the height and width of the image
int originalW = img.Width;
int originalH = img.Height;

//get the new size based on the percentage change
int resizedW = (int)(originalW * _percent);
int resizedH = (int)(originalH * _percent);

//create a new Bitmap the size of the new image
Bitmap bmp = new Bitmap(resizedW, resizedH);
//create a new graphic from the Bitmap
Graphics graphic = Graphics.FromImage((Image)bmp);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
//draw the newly resized image
graphic.DrawImage(img, 0, 0, resizedW, resizedH);
//dispose and free up the resources
graphic.Dispose();
//return the image
bmp.Save(context.Response.OutputStream, ImageFormat.Gif);

return bmp;
}
catch (Exception ex)
{
return null;
}
}




Our final stop through the Wonderful World Of Image Manipulation will be cropping an image. With this method you pass it the name of the image we're cropping, the height & width of the newly cropped image and the x/y coordinates and it will return a cropped image for you


csharp

/// <summary>
/// method for cropping an image
/// </summary>
/// <param name="img">image to crop</param>
/// <param name="width">width of the cropped image</param>
/// <param name="height">height of the cropped image</param>
/// <param name="x">where on x axis to start</param>
/// <param name="y">where on y axis to start</param>
/// <param name="context">HttpContext we're working within</param>
/// <returns></returns>
public Image Crop(string img, int width, int height, int x, int y, HttpContext context)
{
try
{
//create a new image
Image image = Image.FromFile(img);
//create a new Bitmap the size of the image
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);

//set the Bitmap's resolution
bmp.SetResolution(80, 60);

//create a graphics object from the Bitmap
Graphics gfx = Graphics.FromImage(bmp);

//set smooting mode to anti alias
gfx.SmoothingMode = SmoothingMode.AntiAlias;

//set the interpolation mode
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

//set the offset mode
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;

//draw the new image
gfx.DrawImage(image, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);

bmp.Save(context.Response.OutputStream, ImageFormat.Gif);

return bmp;
}
catch (Exception ex)
{
return null;
}
}



And that brings us to the end of this little stroll together. Keep an eye out for more on image manipulation, image manipulation using HttpHandler that we will create. Thanks for reading smile.gif
ahunjet
Nice. Is there source code to download?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.