views:

876

answers:

3

Hello

I've been trying to do this, but for some reason this is just giving me weird results:

int bpp = Screen.PrimaryScreen.BitsPerPixel;
string fontName = "Tahoma";
Font font = new Font(fontName, 10 * bpp, GraphicsUnit.Point);
Bitmap bm = new Bitmap(20 * bpp, 20 * bpp);
Graphics g = Graphics.FromImage(bm);
TextRenderer.DrawText(g, "a", font, new Rectangle(0, 0, 5 * bpp, 6 * bpp), Color.Black);
g.Flush();
pictureBox1.Image = bm;

What am I doing wrong here? I don't see anything printed on the picture. If I remove all bpp references, I can see it, but it's pretty small.

+4  A: 

You are aware that BitsPerPixel describes the color depth (the number of memory bits that are used to describe the color of a pixel), and has nothing to do with resolution?

I assume that what you want to do is to draw the text in a size that is related to the resolution, which you can do by referring to the DpiX and DpiY properties of the Graphics object.

Update

I am not sure if yo need to bring Dpi into the calculation for this. All you need to do is to create a Rectangle that defines the desired size of your text, and then calculate the correct font size to make the text fit inside the rectangle. The following does that (but maximizes the text size both vertical and horizontal direction). It might give you some pointers to solve your problem:

Bitmap bm = new Bitmap(50, 50);
using (Font font = new Font(fontName, 10, GraphicsUnit.Point))
using (Graphics g = Graphics.FromImage(bm))
{
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    StringFormat stringFormat = new StringFormat()
    {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Near
    };
    Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
    // measure how large the text is on the Graphics object with the current font size
    SizeF s = g.MeasureString(text, font);
    // calculate how to scale the font to make the text fit
    float fontScale = Math.Max(s.Width / rect.Width, s.Height / rect.Height);
    using (Font fontForDrawing = new Font(font.FontFamily, font.SizeInPoints / fontScale, GraphicsUnit.Point))
    {
        g.DrawString(text, fontForDrawing, Brushes.Black, rect, stringFormat);
    }


}

And if you want to print the text with a given point size, you don't need to go about measuring; just set the font size:

Bitmap bm = new Bitmap(20, 20);
using (Font font = new Font(fontName, 6, GraphicsUnit.Point))
using (Graphics g = Graphics.FromImage(bm))
{
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    StringFormat stringFormat = new StringFormat()
    {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Near
    };
    Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
    g.DrawString(text, font, Brushes.Black, rect, stringFormat);
}
Fredrik Mörk
No, I am not, lol. So how can I force some text to be written with the desired height?
Jorge Branco
I updated with some code sample that might give you some direction.
Fredrik Mörk
Thanks a lot. Nice code. Problem is that (as in my original code), the size of the font does not seem to be what you set it to.It's always a lot smaller.
Jorge Branco
You are aware, of course, that a 6-point font is very small? As in, almost too small for most people to read?
GalacticCowboy
What unit are you expecting for your height?
GalacticCowboy
GalacticCowboy is correct; anything under 8 points is typically too small for most people. Around 10 or 11 can be considered normal size for regular text.
Fredrik Mörk
A: 

I would try:

int ImgQual = 600;

int Width = 50;

int Height = 50;

Font TextFont = New Font("Tahoma", 14, FontStyle.Bold)

Bitmap bmp = New Bitmap(Width, Height);

bmp.SetResolution(ImgQual, ImgQual);

System.Drawing.Graphics g = Graphics.FromImage(bmp);

System.Drawing.StringFormat sf = New System.Drawing.StringFormat();

sf.Alignment = StringAlignment.Center;

g.DrawString("a", NumberTextFont, Brushes.Black, New RectangleF(0, 0, Width, Height), sf);

return bmp;
Avitus
Put your code in a code block for readability please.
Arve Systad
ImageQualitySetting <- From where comes this from? I googled and I can't seem to find its namespace.
Jorge Branco
Sorry I clipped this code from a project I was working on. The Image quality is of type integer.
Avitus
+1  A: 

There are two primary reasons the "a" is small:

The height of a font is measured using a point size (which is 1/72nd of a inch, quite different from a number of pixels because different computer screens have different numbers of pixels per inch).

Font height is measured from the top of a line of text to the bottom. As some letters have ascenders (the tall bar in "h") and others have descenders (the dangly bit of a "g"), an "a" will occupy only about a third of the height of the font.

If you wish your "a" to fill the image, then you will need to draw it into a larger rectangle and "clip off" the empty regions above and below the "a". If you're not too worried about screen DPI on different computers, then you can just experiment until you find a font size (and position to draw at) that works.

Jason Williams