Page 1 of 1

Image manipulation with GDI+ in C#

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1659
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 26 May 2008 - 11:22 PM

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


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


/// <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


//// <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


/// <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


// 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


/// <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


/// <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


/// <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 :)

This post has been edited by PsychoCoder: 26 May 2008 - 11:25 PM


Is This A Good Question/Topic? 1
  • +

Replies To: Image manipulation with GDI+ in C#

#2 ahunjet  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 31-July 08

Posted 31 July 2008 - 01:53 AM

Nice. Is there source code to download?
Was This Post Helpful? 0
  • +
  • -

#3 alsharafi  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 30-December 08

Posted 30 December 2008 - 02:06 PM

to gray image you can use the follwing C# code
// 
		// Gray Image
		//
		 private void GrPic_Click(object sender, EventArgs e)
		{
			if (!FoundImage)
				MessageBox.Show("You must Select Image ..");
			else
			{   PicBxG.Show();
				int r, g, b;

				Color[,] mat;
				Bitmap Bmp = new Bitmap(PicBxO.Image);
				PicBxG.Image = Bmp;
				mat = new Color[Bmp.Width, Bmp.Height];
				for (int i = 0; i < Bmp.Width; i += 1)
				{
					for (int j = 0; j < Bmp.Height; j += 1)
					   r = Bmp.GetPixel(i, j).R - 10;
						g = Bmp.GetPixel(i, j).G - 10;
						b = Bmp.GetPixel(i, j).B - 10;

						if (r < 0) r = 0;
						if (g < 0) g = 0;
						if (b < 0) b = 0;
						int av = (r + g + b) / 3;
						mat[i, j] = Color.FromArgb(Bmp.GetPixel(i, j).A, av, av, av);//(r, g, b);//;
						Bmp.SetPixel(i, j, mat[i, j]);

					}
					double y = (i + 1) * 100 / Bmp.Width;
					this.Text = Convert.ToString(y) + "%";
					PicBxG.Refresh();
				}
			}
		}


Was This Post Helpful? 0
  • +
  • -

#4 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 160
  • Joined: 17-October 09

Posted 07 February 2010 - 04:41 AM

Hi,

How would i go about cropping an image based on user selection? I would like to crop an image by dragging a rectangle around the image i would like to crop. I would greatly appreciate your help.

How would i go about doing this based on the following code:

Cropping code:
http://www.dreaminco...snippet1987.htm


A tutorial that I worked on
Point lastClick;

 private void frmMove_Paint(object sender, PaintEventArgs e)
        {
            Pen p = new Pen(Color.Gray, 3);
            e.Graphics.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);
            p.Dispose();
        }

       
        private void frmMove_MouseDown(object sender, MouseEventArgs e)
        {
            lastClick = new Point(e.X, e.Y); //need this when form moves.
        }

        private void frmMove_MouseMove(object sender, MouseEventArgs e)
        {
            //Point newLocation = new Point(e.X - lastE.X, e.Y - lastE.Y);
            if (e.Button == MouseButtons.Left) //Only when mouse is clicked
            {
                //Move the Form the same difference the mouse cursor moved
                this.Left += e.X - lastClick.X;
                this.Top += e.Y - lastClick.Y;
            }
        }


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1