formatc
formatc

Reputation: 4323

ASP.NET TextRenderer.DrawText Awful Text Images

Since I've tried to draw string with every combination of smoothing and rendering with Graphics.DrawString() I was thinking that text renderer would do a better job drawing my strings but I think was wrong.

This is how it is supposed to look like:

enter image description here

And this is how it looks like:

enter image description here

Here is my code:

Graphics objGraphics2 = Graphics.FromImage(objBitmap);

objGraphics2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
objGraphics2.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
objGraphics2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
objGraphics2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;

Font textFont = new Font(textFontFamily, PxtoEm(textSize));

SolidBrush b = new SolidBrush(textColor);

TextRenderer.DrawText(objGraphics2, textValue, textFont, new Rectangle(0, 0, Width, Height), textColor);

Is my PxtoEm method wrong?

public float PxtoEm(int px)
{
      float em = (float)(Convert.ToDouble(Convert.ToDouble(px) * Convert.ToDouble(72) / Convert.ToDouble(objBitmap.HorizontalResolution)));
      return em;
}

I need some suggestions because this is really awful, it gets worse with larger fonts and images aren't shrunk.

UPDATE: Got it working with bigger fonts(ie. 20px) but with smaller fonts it gets kind of erased on some letters:

This is how it's suposed to be with font Arial 10px:

enter image description here

This is result with Graphics.DrawString()

enter image description here

As you can see it really isn't very good but closest I got. I made some changes to code and got better results with larger font:

This is how it's suposed to be with font Arial 20px:

enter image description here

This is drawing result:

enter image description here

And here is the changed code(I droped em method and used pixels directly, switched to Graphics.DrawString() instead of TextRenderer.DrawText()

  Graphics objGraphics = Graphics.FromImage(objBitmap);
  objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
  objGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  objGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
  Font textFont = new Font(textFontFamily, textSize,GraphicsUnit.Pixel);
  SolidBrush b = new SolidBrush(textColor);
  PointF origin = new PointF((float)TextLeft,(float)TextTop);
  StringFormat format = StringFormat.GenericTypographic;

  objGraphics.DrawString(textValue, textFont, b , origin, format);

If someone has some suggestion to maybe write different method for smaller text sizes and use above code for larger as it works nicely, post it and I'll try it!

UPDATE 3: Finally found solution for everything, and solution was rather simple: DON'T USE TRANSPARENT BACKGROUND!

And settings are:

 objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // <-- important!
 objGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
 objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
 objGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
          objGraphics.TextContrast = 0;

Here is final image with these settings on white background:

enter image description here

Exactly the same, thanks for suggestions and replies.

Upvotes: 7

Views: 3219

Answers (4)

MyItchyChin
MyItchyChin

Reputation: 14031

I built something to generate image buttons using similar functionality and I had issues with kerneling and the font not stretching to the desired with. The following settings got me really close to what I wanted but still not 100%.

objGraphics2.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
objGraphics2.TextRenderingHint = System.Drawing.Drawing2D.TextRenderingHint.AntiAliasGridFit;

Upvotes: 2

Hogan
Hogan

Reputation: 70523

I'm not sure it will help but why not create your font without the function call, like this:

 Font textFont = new Font(textFontFamily, textSize, GraphicsUnit.Pixel);

Upvotes: 3

Chris Ballance
Chris Ballance

Reputation: 34347

Set Graphics.TextRenderingHint to SingleBitPerPixelGridFit.

Upvotes: 2

Matthew
Matthew

Reputation: 25763

I'm not sure if this will solve the issue, but I had a similar problem with drawing text in Direct3D, check out PixelOffsetMode, set it to Half.

Upvotes: 0

Related Questions