I use this code for drawing text in a panel:
Graphics g = panel1.CreateGraphics();
g.DrawString(...);
So I want to know what size the input text will be when rendered in the panel.
Use g.MeasureString() to get the width of a string in the grapic context.
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont);
You can also use TextRenderer.MeasureText which is sometimes easier to use than MeasureString.
Related
I'm trying to get the height of a string. I've come across MeasureString but it's inaccurate for what I need it for - too small for what MS Word is showing (okay, this is probably another topic so if you can point me to the right resources...)
So, I found out about TextMetrics. I want to try it but I couldn't understand how to use it. Here is my sample code:
static public double MeasureGroup2()
{
TextMetrics txt = new TextMetrics();
double height;
height = txt.Height;
return height;
}
Where/how can I set the font and font size, and the string for it to return the values I need?
P.S. My end goal is to measure the height of a string the same way MS Word "measures" or renders it. I'm open to other solutions other than these two.
Additional info:
Code for MeasureString:
static public double MeasureGroup1(string TextFont, int FSize)
{
string Str = "Mgkfps";
Bitmap Bmp = new Bitmap(99,99);
Graphics DrawGraphics = Graphics.FromImage(Bmp);
GraphicsUnit Unit = GraphicsUnit.Point;
DrawGraphics.PageUnit = Unit;
DrawGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
StringFormat format = StringFormat.GenericTypographic;
// Set up string.
System.Drawing.Font stringFont = new System.Drawing.Font(TextFont, FSize, FontStyle.Regular, Unit);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = DrawGraphics.MeasureString(Str, stringFont, 99, format);
DrawGraphics.Dispose();
format.Dispose();
stringFont.Dispose();
return stringSize.Height;
//return TextSize;
}
Notes:
Using Arial 11, and Arial 12, the output of this code needs to be multiplied by 1.0294 to be the same as how MS Word is showing. Physical measurements were made using Word's ruler, Photoshop, and a lot of ratio-and-proportion. (Maybe this is the problem?)
static public double MeasureGroup2(string TextFont, int FSize)
{
string Str = "Mgkfps";
double height;
Bitmap Bmp = new Bitmap(99, 99);
Graphics DrawGraphics = Graphics.FromImage(Bmp);
GraphicsUnit Unit = GraphicsUnit.Point;
DrawGraphics.PageUnit = Unit;
DrawGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
StringFormat format = StringFormat.GenericTypographic;
// Set up string.
System.Drawing.Font stringFont = new System.Drawing.Font(TextFont, FSize, FontStyle.Regular, Unit);
Rectangle Rect = new Rectangle(0, 0, 99, 99);
Size sz = new Size(99,99);
sz = TextRenderer.MeasureText(DrawGraphics, Str, stringFont, sz ,TextFormatFlags.NoPadding);
height = sz.Height;
return height;
}
First of all, thank you everyone for helping me out!
When using TextMetrics to get the dimensions of a text, refer to this post here:
https://www.cyotek.com/blog/retrieving-font-and-text-metrics-using-csharp
He has a sample project down at the bottom of the page.
As for where I was hoping to use it, which is getting the height of a text in MS Word:
I assumed that the text height and line spacing, when set to single, is the same. This is not the case. There is a small amount of space, the leading, that is not measured by MeasureString. That is why I was hoping to use the GetTextMetrics function since it returns a struct that includes the leading. Anyway, it appears to be used for something else.
Fortunately, and apparently, there is a method native to the .NET framework that returns the value I need which is FontFamily.GetLineSpacing.
LineHeight = stringFont.Size * FF.GetLineSpacing(FontStyle.Regular)/FF.GetEmHeight(FontStyle.Regular);
Reference:
https://answers.microsoft.com/en-us/office/forum/office_2013_release-word/what-reasons-make-different-line-spacing-between/ca1267f9-0cfe-4f26-8048-bbd7a6a46398?auth=1
https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-obtain-font-metrics
In my application, I generate a Bitmap with a variable string.
Here is my function:
public void Image(String text, String font, int size)
{
Font font = new Font(font, size);
float res = ((font.SizeInPoints * text.Length) / 72) * 96;
using (Bitmap img = new Bitmap((int)res, font.Height))
{
Graphics g = Graphics.FromImage(img);
SolidBrush drawBrush = new SolidBrush(Color.Black);
g.DrawString(text, font, drawBrush, 1, 0);
String directory = AppDomain.CurrentDomain.BaseDirectory + "Content\\Images\\Signature\\";
string outputFileName = directory + "sign.png";
img.Save(outputFileName, ImageFormat.Png);
}
}
I would like the width of the image to match perfectly the width of the string printed in that bitmap.
As you can see, I tried to calculate the width with point size of the font.
The problem is that each letter printed has a different width so I can not get the size before creating the Bitmap.
Plus, I don't even know how to retrieve the actual size of the printed string...
Does anyone have an idea?
Use the Graphics.MeasureString function. It takes a string and a font, and returns the size of the rendered text as a SizeF. There are also additional overloads that can take formatting information, and one that takes a SizeF representing the maximum width for wrapping.
Details can be found here: https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Set maximum layout size.
SizeF layoutSize = new SizeF(100.0F, 200.0F);
// Set string format.
StringFormat newStringFormat = new StringFormat();
newStringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont, layoutSize, newStringFormat);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0,
I'm trying to achieve framed texts (using Windows Forms), e.g.:
Height is always the same, because my strings are less than 20 chars. What about width? Is there any way to get it automatically?
Use Graphics.MeasureString()
From MSDN: http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx
private void MeasureStringMin(PaintEventArgs e)
{
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}
If you don't feel like dealing with the Paint eventhandler, you could try the TextRenderer class. It has a static method that is identical to the "MeasureString" method in the above answer. In this class it is called MeasureText however.
I have a couple of TextBlocks in a Fixed Size Column Grid. i.e. The Grid size might change, but its column widths are all the same (e.g. 10% of the whole size) and each column contains a TextBlock.
The font size of all the TextBlocks MUST be the same.
How can I find the maximum possible font size which makes all the texts inside TextBlocks visible?
You could use Graphics.MeasureString Method (String, Font, Int32) to calculate the fontsize.
Then use some behaviour magic to bind the font size to the TextBlock.
private void MeasureStringWidth(PaintEventArgs e)
{
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Set maximum width of string.
int stringWidth = 200;
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont, stringWidth);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}
If I have a System.Drawing.Bitmap with equal dimensions e.g. 100x100, 50x50 and I wanted to use this code to draw in a single character:
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
font = new Font(_fontName, _fontSize, _fontStyle);
GraphicsPath path = new GraphicsPath();
path.AddString("A", font.FontFamily, (int)font.Style, font.Size, rect, stringFormat);
How would I go about calculating the value for _fontSize so that it fits tightly inside the dimensions of the image?
Graphics.MeasureString function returns the size of a string of a given font. In a loop you can determine what font size fits best.
http://msdn.microsoft.com/en-us/library/403ezxd2.aspx
its gonna help u:
float fontsizeem = height;
int charfits=0;int line=2;
for (; charfits < captchastring.Length || line < 1 ; fontsizeem--)//font support style correct // color fix
{
graphic.MeasureString(captchastring, new Font(fontFamily, fontsizeem, fontstyle), new SizeF((float)width*0.6f, (float)height*0.6f), format, out charfits, out line);
}
fontsizeem *= graphic.DpiY /72 ; // this unit converting fucks me out :(((((((
path.AddString(captchastring, fontFamily,(int) fontstyle,fontsizeem,rectangle, format);// -- size