C# Write Text on Bitmap

c# write text on bitmap


Bitmap bmp = new Bitmap("filename.bmp");

RectangleF rectf = new RectangleF(70, 90, 90, 50);

Graphics g = Graphics.FromImage(bmp);

g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawString("yourText", new Font("Tahoma",8), Brushes.Black, rectf);

g.Flush();

image.Image=bmp;

Write text on a bitmap image in C#

It looks like you are drawing on the wrong bitmap

 Bitmap bitMapImage = new Bitmap(Image);
using (Graphics graphImage = Graphics.FromImage(Image))

should be

 Bitmap bitMapImage = new Bitmap(Image);
using (Graphics graphImage = Graphics.FromImage(bitMapImage))

How to add text to a bitmap image programmatically? WPF

You can achieve this using DrawingVisual and DrawingImage classes :

Sample Image

var random = new Random();
var pixels = new byte[256 * 256 * 4];
random.NextBytes(pixels);
BitmapSource bitmapSource = BitmapSource.Create(256, 256, 96, 96, PixelFormats.Pbgra32, null, pixels, 256 * 4);
var visual = new DrawingVisual();
using (DrawingContext drawingContext = visual.RenderOpen())
{
drawingContext.DrawImage(bitmapSource, new Rect(0, 0, 256, 256));
drawingContext.DrawText(
new FormattedText("Hi!", CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
new Typeface("Segoe UI"), 32, Brushes.Black), new Point(0, 0));
}
var image = new DrawingImage(visual.Drawing);
Image1.Source = image;

Unfortunately you will have to create a new BitmapSource as there's currently no way I know of writing text directly to it.

Alternatively you could use WriteableBitmapEx : https://writeablebitmapex.codeplex.com/

  • create a WriteableBitmap from your frame using BitmapFactory (1)
  • create another WriteableBitmap and draw text on it using the above method (2)
  • blit the text bitmap (2) over your frame (1)

Same result but different approach, not sure whether approach 2 is better as it's cumbersome.

Efficient Text Rendering On Bitmap In C# with System.Drawing

So I took the advise of @Raju Joseph in the comments of the question and broke the code up. It's probably not any faster to run now than before but at least it looks neater
so the function that draws the text now looks like this

public static Bitmap Write_Text(Bitmap i, string s, Rectangle r, bool centered, string font, bool bold, bool italic)
{
//Since we want to avoid out of bounds errors make sure the rectangle remains within the bounds of the bitmap
//and only execute if it does
if(r.X>= 0 && r.Y>=0&&(r.X+r.Width < i.Width) && (r.Y + r.Height < i.Height))
{
//Step one is to make a graphics object that will draw the text in place
using (Graphics g = Graphics.FromImage(i))
{
//Set some of the graphics properties so that the text renders nicely
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
//Compositing Mode can't be set since string needs source over to be valid
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
//And an additional step to make sure text is proper anti-aliased and takes advantage
//of clear type as necessary
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

//this also requires a font object we need to make sure we dispose of properly
using (Font f = Functions.Generate_Font(s, font, r, bold, italic))
{
//the using function actually makes sure the font is as large as it can be for the
//purpose of fitting the rectangle we just need to check if its centered
using (StringFormat format = new StringFormat())
{
//the format won't always be doing anything but
//just in case we need it
//and if the text is centered we need to tell the formatting
if (centered)
{
format.Alignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
}
//and draw the text into place
g.DrawString(s, f, Brushes.Black, r, format);
}
}
}
}
return i;
}

With figuring out how big the font needs to be being handled by a different method of the class which is as follow

 public static Font Generate_Font(string s,string font_family, Rectangle r, bool bold, bool italic)
{
//First things first, the font can't be of a size larger than the rectangle in pixels so
//we need to find the smaller dimension as that will constrain the max size
int Max_Size = Math.Min(r.Width, r.Height);
//Now we loop backwards from this max size until we find a size of font that fits inside the
//rectangle given
for(int size = Max_Size; size > 0; size--)
{
//Since a default font is used if the font family specified doesnt exist
//checking the family exists isnt necessary
//However we need to cover if the font is bold or italic
Font f;
if (bold)
{
f = new Font(font_family, size, System.Drawing.FontStyle.Bold, GraphicsUnit.Pixel);
}
else if (italic)
{
f = new Font(font_family, size, System.Drawing.FontStyle.Italic, GraphicsUnit.Pixel);
}
else if (bold && italic)
{
//the pipe is a bitwise or and plays with the enum flags to get both bold and italic
f = new Font(font_family, size, System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic, GraphicsUnit.Pixel);
}
else
{
//otherwise make a simple font
f = new Font(font_family, size, GraphicsUnit.Pixel);
}
//because graphics are weird we need a bitmap and graphics object to measure the string
//we also need a sizef to store the measured results
SizeF result;
using(Bitmap b = new Bitmap(100,100))
{
using(Graphics g = Graphics.FromImage(b))
{
result = g.MeasureString(s, f);
}
}
//if the new string fits the constraints of the rectangle we return it
if(result.Width<= r.Width && result.Height <= r.Height)
{
return f;
}
//if it didnt we dispose of f and try again
f.Dispose();
}
//If something goes horribly wrong and no font size fits just return comic sans in 12 pt font
//that won't upset anyone and the rectangle it will be drawn to will clip the excess anyway
return new Font("Comic Sans", 12, GraphicsUnit.Point);
}

Probably some other way of doing that but this seems fast enough and it looks neat enough in source so thumbs up for that.

How to Write Text On a Image with Centered Position C#

You text is indeed centered in the rectangle you created. The problem is that the rectangle you based it off the ClientSize Height and Width which come from the control you are inside.

What you want to use is the current Bitmap properties for Height and Width.

instead of :

 Rectangle rect = new Rectangle(0, 0, ClientSize.Width - 10, ClientSize.Height - 10);     

you want :

Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); 

How do I write text on WriteableBitmap?

You can share the Pixel buffer between a Bitmap and a BitmapSource

var writeableBm1 = new WriteableBitmap(200, 100, 96, 96, 
System.Windows.Media.PixelFormats.Bgr24, null);

var w = writeableBm1.PixelWidth;
var h = writeableBm1.PixelHeight;
var stride = writeableBm1.BackBufferStride;
var pixelPtr = writeableBm1.BackBuffer;

// this is fast, changes to one object pixels will now be mirrored to the other
var bm2 = new System.Drawing.Bitmap(
w, h, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, pixelPtr);

writeableBm1.Lock();

// you might wanna use this in combination with Lock / Unlock, AddDirtyRect, Freeze
// before you write to the shared Ptr
using (var g = System.Drawing.Graphics.FromImage(bm2))
{
g.DrawString("MyText", new Font("Tahoma", 14), System.Drawing.Brushes.White, 0, 0);
}

writeableBm1.AddDirtyRect(new Int32Rect(0, 0, 200, 100));
writeableBm1.Unlock();

Write text on an image in C#

To draw multiple strings, call graphics.DrawString multiple times. You can specify the location of the drawn string. This example we will draw two strings "Hello", "Word" ("Hello" in blue color upfront "Word" in red color):

string firstText = "Hello";
string secondText = "World";

PointF firstLocation = new PointF(10f, 10f);
PointF secondLocation = new PointF(10f, 50f);

string imageFilePath = @"path\picture.bmp"
Bitmap bitmap = (Bitmap)Image.FromFile(imageFilePath);//load the image file

using(Graphics graphics = Graphics.FromImage(bitmap))
{
using (Font arialFont = new Font("Arial", 10))
{
graphics.DrawString(firstText, arialFont, Brushes.Blue, firstLocation);
graphics.DrawString(secondText, arialFont, Brushes.Red, secondLocation);
}
}

bitmap.Save(imageFilePath);//save the image file

Edit: "I Add a load and save code".

You can open the bitmap file any time Image.FromFile, and draw a new text on it using the above code. and then save the image file bitmap.Save

Print Text with DrawString() next to an existing bitmap

The image you're drawing on (batchCode) is 80 pixels wide and 700 high. When you write your text over it, you set the top-left point of your writing to 80,700 - exactly to the bottom-right corner of your picture. Basically, you write your text outside of the picture.

Update

I've created a small example to make it reproducible, below is a form class for a basic WinForms application:

public partial class Form1 : Form
{
private PictureBox pictureBox2;

public Form1()
{
InitializeComponent();

pictureBox2 = new PictureBox();
pictureBox2.Size = ClientSize;
pictureBox2.SizeMode = PictureBoxSizeMode.AutoSize;
this.Click += Form1_Click;
pictureBox2.Click += Form1_Click;

Controls.Add(pictureBox2);
}

private void Form1_Click(object sender, EventArgs e)
{
var batch = "hello there!";

Bitmap batchCode = new Bitmap(1000, 1000);
var batch1 = new RectangleF(150, 150, 850, 850);
using (Graphics g = Graphics.FromImage(batchCode))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.DrawString(batch, new Font("Arial", 40), Brushes.Black, batch1);
}
pictureBox2.Image = batchCode;
}
}


Related Topics



Leave a reply



Submit