C# Snippet Tutorial - How to Draw Text on an Image

Skill

C# Snippet Tutorial - How to Draw Text on an Image

Posted in:

In this snippet tutorial we're going to be adding on to our series of C# image editing tutorials. This tutorial is going to provide the code required to do basic text drawing including anti-aliasing and text alignment.

For more information on C# image editing, check out our previous two tutorials: C# Tutorial - Image Editing: Saving, Cropping, and Resizing and C# Tutorial - Image Editing: Rotate.

Ok, let's get started. The first thing we need to do is get a Bitmap object from an image file.

Bitmap myBitmap = new Bitmap("C:\\myImage.jpg");

Now that we have a Bitmap object we can get a Graphics object from it. The Graphics object will be doing all of our text drawing.

Bitmap myBitmap = new Bitmap("C:\\myImage.jpg");
Graphics g = Graphics.FromImage(myBitmap);

We can now use this Graphics object to perform all of our drawing. Let's start by simply placing some text in the upper left corner.

g.DrawString("My\nText", new Font("Tahoma", 40), Brushes.White, new PointF(0, 0));

This call will place white text in the upper left corner of your image.

Image Width Text Drawn On It

C# Tutorial - Image Editing: Saving, Cropping, and Resizing has lots of information on how to resize and save your new image. It's kind of hard to see in the above example but the edges on that text are a little rough. Let's look at how to anti-alias the text to make it look a little smoother.

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("My\nText", new Font("Tahoma", 20), Brushes.White, new PointF(0, 0));

Here we set the TextRenderingHint to AntiAlias before we draw the text. Now all consecutive calls to DrawString will output anti-aliased text. Now that we have the basics down for putting text on the image, let's look at how to do some text aligning. We'll start with some horizontal alignment.

StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
g.DrawString("My\nText", new Font("Tahoma", 20), Brushes.White,
    new RectangleF(0, 0, 500, 500), strFormat);

The StringFormat class has lots of options for formatting strings, but we're going to be focusing on the ones that control alignment. The Alignment property controls the horizontal alignment and I set it to StringAlignment.Center, which will center the text at the top of the image. A also modified the DrawString function to take a Rectangle, which for simplicity I just set to the entire size of the image. The last argument is the StringFormat object.

Image With Text Centered Horizontally

So now that we have the text centered horizontally, let's center it vertically. Now the text will be put right in the center of the image.

StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
g.DrawString("My\nText", new Font("Tahoma", 20), Brushes.White,
    new RectangleF(0, 0, 500, 500), strFormat);

The only thing I added to make this happen was setting the StringFormat.LineAlignment property to StringAlignment.Center.

Image with text in the center

That's it for drawing text on an image. You can of course make all sorts of neat text effects using Brushes and Formats, but I'll leave all of that up to you. Remember to check out C# Tutorial - Image Editing: Saving, Cropping, and Resizing and C# Tutorial - Image Editing: Rotate for lots of other information on images and C#. The image I used for my examples can be downloaded from Gaming Textures.

Fuego
09/24/2007 - 03:23

Hello there ! Reaaly great code you wrote here...
I was wondering how you could get a Rectangle Buffer of the image. Imagine you want to do some animation let's say a vertical scrolling, well you would have to Redraw the rectangle you just took in buffer before you draw the text and then move the location of the text...

reply

Abdullah Ansari
10/25/2007 - 01:51

A nicely written code and simpler explaination.

Really a good work.

Thanks,
Abdullah

reply

kjhg
05/18/2008 - 01:01

Sample doesn't work!!! No text appearing on image!!!

reply

Anonymous
07/13/2008 - 00:08

Remember to call the Bitmap.Save() method to save the results of the object manipulation. That should do it.

reply

chandan
05/29/2008 - 17:17

i want to read text from an image file. How do i do that

reply

Brian P
08/22/2008 - 09:23

Excellent code! Exactly what I needed!

reply

Mehregan
08/24/2008 - 12:32

That was great.
Thanks

reply

Jay
09/02/2008 - 17:20

Nice code. Very clean and simple.

reply

Ed
10/05/2008 - 17:53

Great article. Any idea how you would add drop shadow to the text?

Thanks!

reply

Wachid
10/07/2008 - 07:21

simple, structured, nice documented.

hopefully we could share more code snippet, since my site also dedicated for programming and information technology issue.

nice to meet you,

-wachid-

reply

Jenny
10/07/2008 - 19:12

Nice code. Easy to use and works well. I've a ?? though. If you wanted to use differents fonts, would they have to be on your server, or the client machine?

reply

The Reddest
10/08/2008 - 07:56

I targeted this tutorial towards desktop application developers, but I guess it could also be used in ASP.NET web sites (which I'm guessing you're doing).

In that case, the font would have to be on the server.

reply

D
11/12/2008 - 07:51

You're an idiot.

reply

The Reddest
11/12/2008 - 10:47

D, I think it's a perfectly valid question. Especially with the rise of client-side technologies like Silverlight.

reply

Anonymous
08/24/2011 - 16:11

You're an idiot.

reply

ddboarm
05/19/2009 - 14:21

I have a Panel control on which I am performing:

xGrfc.DrawString(myStr, xFont, xBrush, 5, 5);

The first time this is proc'd there is no problems. When an event occurs, however, and the DrawString is proc'd, I receive and invalid parameter error. What do I need to do to get the DrawString to function. Essentially, I am wanting to redraw a new string.

Thanks in advance...
David

reply

The Reddest
05/19/2009 - 14:34

Where are you calling this code? I think the problem might be that you're holding on to the Graphics object too long. When OnPaint is called, the Graphics object can only exist for the duration of that function. You can't save it to a variable and attempt to use it again. When the event occurs, change myStr and call Invalidate, which will force the Panel to call OnPaint, where you can get a new Graphics object call DrawString again with the new text.

reply

ddboarm
05/19/2009 - 15:35

That makes sense. I am taking the first PaintEventArgs e and storing to a variable for later use. Thanks much...I'll let you know what happens!!!

David

reply

ddboarm
05/19/2009 - 23:30

Invalidate() did the trick!!! Thanks...

David

reply

The Reddest
05/20/2009 - 08:47

If you want to be a little more efficient, you can use the Invalidate overload that takes a rectangle. That way you don't have to redraw the entire Panel just to change the text.

reply

lil_boy
08/01/2009 - 22:31

was having a problem how to make the font work but now its working, thanks

reply

sam
08/25/2009 - 09:13

Hi,
Nice tutorial

I've tried your code and the only problem I have with it is that once I've saved the image with the added text, its size grows from 2 Mb to 9 Mb !
Is there any way to keep the original image settings ?
Thanks

reply

The Reddest
08/25/2009 - 09:22

How are you saving the image? This tutorial shows you how to save images with compression - like jpeg.

reply

sam
08/25/2009 - 09:37

You are right I was not saving it properly. Now it's better but it still a few kilobytes bigger than the original. If it's the original is serveral Mbytes big, it's not a huge issue, however if the original is, say 65 Kb, it ends up being 175 Kb, and that's an issue to me.

This is my code, is there anything wrong with this ? :

 public void AddWatermark(string pPath, string pWatermark){
      Image image = Image.FromFile(pPath);      
      Bitmap bmp = new Bitmap(image);
      bmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);

      ImageCodecInfo iciJpegCodec = null;
      //find the correct Codec and specify its quality
      EncoderParameter epQuality = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
      // Get all image codecs that are available
      ImageCodecInfo[] iciCodecs = ImageCodecInfo.GetImageEncoders();
      // Store the quality parameter in the list of encoder parameters
      EncoderParameters epParameters = new EncoderParameters(1);
      epParameters.Param[0] = epQuality;
      // Loop through all the image codecs
      for (int i = 0; i < iciCodecs.Length; i++)
      {
        // Until the one that we are interested in is found, which is image/jpeg
        if (iciCodecs[i].MimeType == "image/jpeg")
        {
          iciJpegCodec = iciCodecs[i];
          break;
        }
      }

      using (Graphics gr = Graphics.FromImage(bmp))
      {
        gr.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height));
        gr.DrawString(pWatermark, new Font("Arial", 10), Brushes.White, new PointF(5, bmp.Height - 20));
      }

      bmp.Save(pPath + "test", iciJpegCodec, epParameters);
      bmp.Dispose();
    }      

reply

The Reddest
08/25/2009 - 10:23

You're saving the jpeg with 100% quality. Most of the time you can reduce that to around 80%-85% without any noticeable difference. That will also reduce the size of the image quite a bit.

reply

Dominic
10/26/2009 - 21:43

Thank you very much. Just in case people don't know, to display the image, you need something like a picturebox- in this case, just drag a picturebox control onto your form, then simple use pictureBox1.Image = myBitmap; after all the code from this tutorial to display it.

reply

Anonymous
02/28/2010 - 08:46

hi dear!
very teribble
in the iran very simple designed by our student.

reply

Jalal
03/10/2010 - 19:51

I do not know how to thank you

Thank you very much

reply

ZD
06/03/2010 - 10:37

Hi there,

I wondered if there was a way to insert an "Editable" text box inside of an image with the use of C#??

Let me explain: I would like to create an image that would allow the user to insert text, such as the image name, into the image at any time.

Thanks for answering!

ZD

reply

The Reddest
06/03/2010 - 11:10

I'd probably do something like this with controls. I'd layer a label on top of the image and listen for the click event. When it's clicked, place a textbox where the label was. When 'enter' is hit, or the textbox loses focus, swap it out for the label. When the user hits a 'save' button or something, that's when I'd use the code in this tutorial to generate the final image.

reply

ZD
06/07/2010 - 10:39

Thanks a lot for your help sir, it's very appreciated!

reply

no no no
07/15/2010 - 01:58

it's code no no no.....

reply

45
07/15/2010 - 02:03

it's nice tutorials.
problem text to image save?...

reply

45
07/15/2010 - 02:38

nice nice good job..

reply

MrP
07/26/2010 - 03:34

Hello!
Thx 4 this tutorial.

could somebody explain how to draw on graphics in the "Portable Network Graphic" format?

Mr P.

reply

Babuji
07/28/2010 - 06:22

i got it text added to picture.but i want to video background added any logo or text.how to added send to me c# source

Thanks
babuji

reply

babuji
07/29/2010 - 02:16

i want to video background start to end staying for some text added in C# code. urgent to me that source code please help me

reply

Dino
07/31/2010 - 16:29

PARKOUR
TEAM
SOLGERS

reply

Anonymous
10/31/2010 - 14:22

Thanks
This code is very useful for me
Thanks again

reply

Sanjeev
12/20/2010 - 20:49

Can we have a dynamically created html table with rows/ columns / text saved in the image as above...

reply

Anonymous
12/21/2010 - 12:54

Thanks,

System.Drawing.Text.TextRenderingHint.SingleBitPerPixel

it's just i`m looking for to draw barcodes into jpeg files and not antialiasing to read with scanner.

Thanks so much

reply

Juan
01/05/2011 - 18:58

Hi

Thanks for the code works great. I would like to know if i wanted to select a default image as background and also add text as described above i would also like to add another smaller image also to the default image (I am trying to create a weather image with a background, text for tempture, and second image(smaller one) as the weather condition i.e. sun, or moon, or rain). how can i add the second image could you provide a sample snippet of code??

reply

Juan
01/05/2011 - 19:53

Disreguard post I got it figured out..

thanks once again for the code samples..

reply

Sumit
01/08/2011 - 08:05

a small but very useful bunch of code... just what i was lookin... thanx man...!!!

reply

Anonymous
03/18/2011 - 20:46

Nice and quick, perfect! Cheers

reply

Anonymous
09/29/2011 - 07:06

any way to get the source as a solution file?

reply

Tobbyolu
02/01/2012 - 07:16

What are gud job. thanks

reply

Anonymous
03/15/2012 - 10:10

Not working with me :S

This is my test code

Bitmap myBitmap = new Bitmap("G:\\myImage.jpg");
Graphics g = Graphics.FromImage(myBitmap);

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("My\nText", new Font("Tahoma", 50), Brushes.White, new PointF(0, 0));

reply

The Reddest
03/15/2012 - 13:09

Did you save the image back to the file?

reply

Varinder Rai
05/03/2012 - 00:26

Hi.... I am windows developer

I am also doing same but my problem is that when i take print of document in which i have use watermark. The watermark color is dark as like other strings. It is happening because printer treat it as normal text. I want to know is there anyway to tell Printer to draw watermark light.

Thanks.

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.