首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Graphics.DrawString时动态调整字体大小以适应空间

使用Graphics.DrawString时动态调整字体大小以适应空间
EN

Stack Overflow用户
提问于 2013-10-30 05:46:24
回答 5查看 23.9K关注 0票数 19

是否有人有提示,而您可以动态调整字体大小以适应特定区域?例如,我有一个800x110矩形,我想用最大字体填充它,以支持我试图显示的整个字符串。

代码语言:javascript
运行
复制
Bitmap bitmap = new Bitmap(800, 110);

using (Graphics graphics = Graphics.FromImage(bitmap))
using (Font font1 = new Font("Arial", 120, FontStyle.Regular, GraphicsUnit.Pixel))
{
    Rectangle rect1 = new Rectangle(0, 0, 800, 110);

    StringFormat stringFormat = new StringFormat();
    stringFormat.Alignment = StringAlignment.Center;
    stringFormat.LineAlignment = StringAlignment.Center;

    graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
    graphics.DrawString("Billy Reallylonglastnameinstein", font1, Brushes.Red, rect1, stringFormat);
} 

bitmap.Save(Server.MapPath("~/Fonts/" + System.Guid.NewGuid() + ".png"));

显然,全名不会在大字体大小的空格中呈现。一定有一种简单的方法吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-10-30 06:01:31

您应该在Font.Size上进行缩放转换,下面的函数就是这样做的一个例子,但是您可以改进它以应用更好的结果。

这里是FindFont函数,它得到一个房间和一个文本的优先大小,并给你一个字体,你可以设置整个文本适合房间!

代码语言:javascript
运行
复制
// This function checks the room size and your text and appropriate font
//  for your text to fit in room
// PreferedFont is the Font that you wish to apply
// Room is your space in which your text should be in.
// LongString is the string which it's bounds is more than room bounds.
private Font FindFont(
   System.Drawing.Graphics g,
   string longString,
   Size Room,
   Font PreferedFont
) {
   // you should perform some scale functions!!!
   SizeF RealSize = g.MeasureString(longString, PreferedFont);
   float HeightScaleRatio = Room.Height / RealSize.Height;
   float WidthScaleRatio = Room.Width / RealSize.Width;

   float ScaleRatio = (HeightScaleRatio < WidthScaleRatio)
      ? ScaleRatio = HeightScaleRatio
      : ScaleRatio = WidthScaleRatio;

   float ScaleFontSize = PreferedFont.Size * ScaleRatio;

   return new Font(PreferedFont.FontFamily, ScaleFontSize);
}

对于您的问题,您可以像下面的代码那样调用它:

代码语言:javascript
运行
复制
Bitmap bitmap = new Bitmap(800, 110);

using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
using (Font font1 = new Font("Arial", 120, FontStyle.Regular, GraphicsUnit.Pixel))
{
   Rectangle rect1 = new Rectangle(0, 0, 800, 110);

   StringFormat stringFormat = new StringFormat();
   stringFormat.Alignment = StringAlignment.Center;
   stringFormat.LineAlignment = StringAlignment.Center;
   graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

   Font goodFont = FindFont(graphics, "Billy Reallylonglastnameinstein", rect1.Size, font1);

   graphics.DrawString(
      "Billy Reallylonglastnameinstein",
      goodFont,
      Brushes.Red,
      rect1,
      stringFormat
   );
}
票数 28
EN

Stack Overflow用户

发布于 2014-05-26 07:16:53

我调整了赛义德的伟大功能,以更符合我的要求。评论意见解释了所有:

代码语言:javascript
运行
复制
    // You hand this the text that you need to fit inside some
    // available room, and the font you'd like to use.
    // If the text fits nothing changes
    // If the text does not fit then it is reduced in size to
    // make it fit.
    // PreferedFont is the Font that you wish to apply
    // FontUnit is there because the default font unit is not
    // always the one you use, and it is info required in the
    // constructor for the new Font.
    public static void FindGoodFont(Graphics Graf, string sStringToFit,
                                    Size TextRoomAvail, 
                                    ref Font FontToUse,
                                    GraphicsUnit FontUnit)
    {
        // Find out what the current size of the string in this font is
        SizeF RealSize = Graf.MeasureString(sStringToFit, FontToUse);
        Debug.WriteLine("big string is {0}, orig size = {1},{2}",
                         sStringToFit, RealSize.Width, RealSize.Height);
        if ((RealSize.Width <= TextRoomAvail.Width) && (RealSize.Height <= TextRoomAvail.Height))
        {
            Debug.WriteLine("The space is big enough already");
            // The current font is fine...
            return;
        }

        // Either width or height is too big...
        // Usually either the height ratio or the width ratio
        // will be less than 1. Work them out...
        float HeightScaleRatio = TextRoomAvail.Height / RealSize.Height;
        float WidthScaleRatio = TextRoomAvail.Width / RealSize.Width;

        // We'll scale the font by the one which is furthest out of range...
        float ScaleRatio = (HeightScaleRatio < WidthScaleRatio) ? ScaleRatio = HeightScaleRatio : ScaleRatio = WidthScaleRatio;
        float ScaleFontSize = FontToUse.Size * ScaleRatio;

        Debug.WriteLine("Resizing with scales {0},{1} chose {2}",
                         HeightScaleRatio, WidthScaleRatio, ScaleRatio);

        Debug.WriteLine("Old font size was {0}, new={1} ",FontToUse.Size,ScaleFontSize);

        // Retain whatever the style was in the old font...
        FontStyle OldFontStyle = FontToUse.Style;

        // Get rid of the old non working font...
        FontToUse.Dispose();

        // Tell the caller to use this newer smaller font.
        FontToUse = new Font(FontToUse.FontFamily,
                                ScaleFontSize,
                                OldFontStyle,
                                FontUnit);
    }
票数 4
EN

Stack Overflow用户

发布于 2017-11-09 22:11:51

这只是对@Saeed的FindFont函数的一个更新。

GraphicsUnit.Pixel需要添加到FindFont函数返回行中。如果没有GraphicsUnit.Pixel,系统dpi将影响绘制的字符串。当系统的dpi和位图不匹配时,就会出现问题。您可以在这个Windows设置影响Graphics.DrawString中看到更多的细节。由于GraphicsUnit of PreferedFont已经设置为GraphicsUnit.Pixel并返回字体,所以没有用GraphicsUnit.Pixel设置字体。在本例中,如果位图dpi大于system,字体大小将小于预期大小,则文本将超出Room维度,如果位图dpi小于system。这是更新的函数。

代码语言:javascript
运行
复制
    private Font FindFont(  System.Drawing.Graphics g , string longString , Size Room , Font PreferedFont)
    {
        SizeF RealSize = g.MeasureString(longString, PreferedFont);
        float HeightScaleRatio = Room.Height / RealSize.Height;
        float WidthScaleRatio = Room.Width / RealSize.Width;
        float ScaleRatio = (HeightScaleRatio < WidthScaleRatio) ? ScaleRatio = HeightScaleRatio : ScaleRatio = WidthScaleRatio;
        float ScaleFontSize = PreferedFont.Size * ScaleRatio;
        return new Font(PreferedFont.FontFamily, ScaleFontSize,PreferedFont.Style,GraphicsUnit.Pixel);
    }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19674743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档