我尝试将C#中的字符串(单个字符)绘制到位图的精确位置:
Bitmap bmp = new Bitmap(64, 64);
Graphics g = Graphics.FromImage(bmp);
g.DrawString("W", font1, new SolidBrush(myColor), new Point(32,32);
在一个字母周围有很多空白空间,我无法猜到“需要”的位置来绘制角色,使其在最后的正确位置。
到目前为止,我有像素的精确尺寸(查看单独渲染的位图中的位)。但是如果我不能在准确位置(例如中心或右上角或......)绘制角色,这些信息就没用了。
是否还有其他方法可以在位图上用C#绘制文本?或者是否有任何转换方法来转换DrawString需要的实际像素位置?
答案 0 :(得分:3)
无需查看像素或开始使用自己的字体..
您可以使用GraphicsPath
代替DrawString
或TextRenderer
,因为它会通过GraphicsPath.GetBounds()
通知您净边界矩形。
如果您知道,可以使用Graphics
计算如何移动TranslateTransform
对象:
private void button1_Click(object sender, EventArgs e)
{
string text = "Y"; // whatever
Bitmap bmp = new Bitmap(64, 64); // whatever
bmp.SetResolution(96, 96); // whatever
float fontSize = 32f; // whatever
using ( Graphics g = Graphics.FromImage(bmp))
using ( GraphicsPath GP = new GraphicsPath())
using ( FontFamily fontF = new FontFamily("Arial"))
{
testPattern(g, bmp.Size); // optional
GP.AddString(text, fontF, 0, fontSize, Point.Empty,
StringFormat.GenericTypographic);
// this is the net bounds without any whitespace:
Rectangle br = Rectangle.Round(GP.GetBounds());
g.DrawRectangle(Pens.Red,br); // just for testing
// now we center:
g.TranslateTransform( (bmp.Width - br.Width ) / 2 - br.X,
(bmp.Height - br.Height )/ 2 - br.Y);
// and fill
g.FillPath(Brushes.Black, GP);
g.ResetTransform();
}
// whatever you want to do..
pictureBox1.Image = bmp;
bmp.Save("D:\\__test.png", ImageFormat.Png);
}
让我们更好地看到中心的小型测试程序:
void testPattern(Graphics g, Size sz)
{
List<Brush> brushes = new List<Brush>()
{ Brushes.SlateBlue, Brushes.Yellow,
Brushes.DarkGoldenrod, Brushes.Lavender };
int bw2 = sz.Width / 2;
int bh2 = sz.Height / 2;
for (int i = bw2; i > 0; i--)
g.FillRectangle(brushes[i%4],bw2 - i, bh2 - i, i + i, i + i );
}
GetBounds
方法返回RectangleF
;在我的例子中,它是{X=0.09375, Y=6.0625, Width=21, Height=22.90625}
。请注意,由于四舍五入的事情总是一个接一个..
您可能希望也可能不希望将Graphics
设置更改为特殊Smoothingmodes
等。
另外应该注意的是,这将通过边界矩形进行自动即机械定心。这可能与'optical or visual centering'完全不同,后者很难编码,在某种程度上也是个人品味的问题。但排版既是一种艺术也是一种职业。