如何计算数字的正确宽度(以像素为单位)?

2024-03-27

我有一个自定义控件,将来可能有用户可自定义的字体(缩放已经实现)。我必须在两位数字下方填充一个矩形,形成以 10 为基数的数字。我对零个、一个或两个数字有不同的颜色。

使用字体 {Name =Microsoft Sans Serif Size=16以及以下内容Graphics.MeasureString方法调用:

g.MeasureString("00", Font);
g.MeasureString("0", Font);

I get:

  • “00”的大小为{宽度=31.5486088高度=26.8124962}
  • “0”的大小为{宽度=19.3298588高度=26.8124962}

“0”的宽度比“00”宽度的一半大很多。

我知道这些方法图形.测量字符串 https://learn.microsoft.com/en-us/dotnet/api/system.drawing.graphics.measurestring,它有很多重载,而且我也知道 StringFormat 类。如何正确计算“0”字符的宽度?

因为字体是用户可自定义的,所以我不想使用等宽字体来解决问题。

如果我使用以下调用:

g.MeasureString("00", Font, 999, StringFormat.GenericTypographic);
g.MeasureString("0", Font, 999, StringFormat.GenericTypographic);

“0”的宽度似乎是“00”宽度的一半,但是当用较小的字体大小绘制时,数字会重叠:

Update:在 UserControl 的 OnPaint 方法中,我有以下代码:

Graphics g = e.Graphics;

int[] indices = { 0, 1 };
CharacterRange[] charRanges = new CharacterRange[indices.Length];
for (int chx = 0; chx < indices.Length; ++chx)
{
    charRanges[chx] = new CharacterRange(indices[chx], 1);
}

StringFormat sf = new StringFormat(StringFormat.GenericDefault);
sf.SetMeasurableCharacterRanges(charRanges);

Region[] regions = e.Graphics.MeasureCharacterRanges("01", Font, e.ClipRectangle, sf);

RectangleF[] r = new RectangleF[regions.Length];
int i = 0;
foreach (Region rr in regions)
{
    r[i] = rr.GetBounds(g);
    g.DrawRectangle(Pens.Blue, r[i].X, r[i].Y, r[i].Width, r[i].Height);
    ++i;
}

g.DrawString("0", Font, Brushes.Black, r[0], sf);
g.DrawString("1", Font, Brushes.Black, r[1], sf);

字体是{Name = "Microsoft Sans Serif" Size=25}。运行程序时,可以看到以下内容:

我想让数字位于蓝色矩形的中心。 UserControl 中的矩形必须尽可能大,但也要​​为 UserControl 高度的百分比留出空间。字体应适应矩形。


需要进行一些小的调整才能使这项工作按预期进行:

  1. TextRenderingHint.ClearTypeGridFit渲染文本时给出更好的结果。
    它更精确,并且与网格拟合特性配合得很好Graphics.DrawString.
    有关此问题的更多信息,请参阅下面链接的答案中的注释。
  2. StringFormat水平和垂直维度上的对齐。
  3. 一种修改后的方法,允许绘制任意长度的字符串。
    如果字符串大于容器,它将使用当前设置进行换行。
  4. 不相关:Brush and Pen在 Paint 事件之外声明,以允许在需要时重新定义它们。

不同的实现MeasureCharacterRanges here:
如何突出显示控件中的换行文本 https://stackoverflow.com/a/48257170/7444103

About Graphics.DrawString and TextRenderingHint.ClearTypeGridFit:
在位图上绘制长字符串会导致绘图问题 https://stackoverflow.com/a/49953353/7444103


Font 48em:
MeasureCharacterRanges 1

Font 16em:
MeasureCharacterRanges 2

Font 9em:
MeasureCharacterRanges 3

Pen pen = new Pen(Color.LightGreen, 1);
Brush brush = new SolidBrush(Color.White);
string sourceDigits = "010011001";

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

    CharacterRange[] charRanges = new CharacterRange[sourceDigits.Length];
    for (int chx = 0; chx < sourceDigits.Length; ++chx) {
        charRanges[chx] = new CharacterRange(chx, 1);
    }

    using (StringFormat sf = new StringFormat())
    {
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Center;
        sf.SetMeasurableCharacterRanges(charRanges);

        Region[] regions = e.Graphics.MeasureCharacterRanges(sourceDigits, Font, e.ClipRectangle, sf);
        for (int i = 0; i < regions.Length; i++) {
            RectangleF rect = regions[i].GetBounds(e.Graphics);
            e.Graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
            e.Graphics.DrawString(char.ToString(sourceDigits[i]), Font, brush, rect, sf);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何计算数字的正确宽度(以像素为单位)? 的相关文章

随机推荐

  • .Net 中值类型有什么用?

    The 官方指南 http msdn microsoft com en us library y23b5415 aspx表明这些的实际用途很少 有没有人有例子说明他们在哪里充分利用了它们 相反 您会发现 C C 人们涌向结构 又称值类型 一
  • 如何在 python 中对 POST 方法进行单元测试?

    我有一个方法可以将包含 JSON 的 POST 发送到 Elasticsearch 实例 我正在尝试编写一个单元测试来验证发送的 JSON 的内容 但我不确定如何进行 我应该在 python 中创建一个本地服务器并让它验证 POST 的内容
  • .NET 4 构建期间未找到 LC.exe 文件

    我在迁移到 net 4 0 时遇到问题 在尝试构建时出现以下错误 C WINDOWS Microsoft NET Framework v4 0 30319 Microsoft Common targets 1917 9 error MSB3
  • vb6 打开文件以追加问题路径未找到

    Open App Path Folder str 0 For Output 似乎找不到一条路径 但是如果就在这之前我就找到了 MsgBox App Path Folder str 0 它提供了我想要的正确目录 文件名 如果我用引号中的直接路
  • 有没有办法访问之前在“heightForRowAtIndexPath”中计算的行高?

    我在方法 heightForRowAtIndexPath 中计算行的高度 但我需要在方法 cellForRowAtIndexPath 中使用该值 有没有办法访问已经计算的值 或者我需要再次进行计算 Thks Gotye None
  • Rails 使用缩写对模型进行非正统命名

    在我正在构建的应用程序中 我使用以下命令在数据库中存储 XML 文件acts as tree协会 我想给班级起个名字XMLElement但这会偏离轨道 因为大写是非标准的 它正在寻找XMLElement从文件名xml element rb
  • Scavenger:分配失败 - JavaScript 堆内存不足

    这是错误消息 lt Last few GCs gt 2383 0x7efe08001450 6100 ms Scavenge 30 3 39 5 gt 30 5 42 7 MB 73 5 0 0 ms average mu 1 000 cu
  • 为什么“git mergetool”(meld)显示冲突标记?

    为什么 git mergetool meld 向我显示带有 conclict 标记的祖先视图 这是完全错误的 我一直不明白为什么会这样做 我该如何修复它 应该显示 3 路合并 Your Changes Common Base Upstrea
  • chaquopy代码在哪个目录中搜索Android应用程序代码的Python代码中导入的Python包

    我已在 chaquopy Android 应用程序的 Python 代码的主要方法中导入了 nltk 库 它要求我实施nltk download punkt 供我处理 所以我想知道 代码在哪个目录中查找包 以便我可以在所需的文件夹中下载它们
  • 如何将数据传回父窗口?

    我找到了一个链接 显示如何将参数发送回打开器浏览器窗口 但它仅适用于window showmodal 如果我使用的话 应该有一个简单的方法可以做到同样的事情window open right 如果您使用 window open 则可以调用父
  • QThread::start(优先级) 与 Linux

    我正在使用一些QThread基于 KDE Neon 18 04 中的工作线程 基于 Ubuntu 18 04 内核 4 15 0 46 generic 工作线程干扰了我的桌面应用程序 因此我决定降低它们的优先级 Qt 文档QThread s
  • Syslog 真的有 1KB 消息限制吗?

    Syslog 似乎有 1KB 消息限制 这是硬编码到 Syslog 协议中的 还是可以为每个服务器设置的参数 我希望我读到的文章已经过时 所以如果您有任何信息 请分享 这是正确的 正如在系统日志协议 RFC https www rfc ed
  • 从 PHP/Apache 返回 100-Continue

    我正在尝试找到一种方法来防止脚本将不必要的数据上传到 PHP 脚本 我最初试图终止传入的读取连接 这显然违反了 HTTP 协议 我无法让它工作 但我一直在研究替代方案 发现100 Continue状态码正是我所需要的 我的客户应该发送所需的
  • AES密钥导出函数

    我有一个 bash 脚本 它使用 openssl 加密数据 并使用 Java 代码解密结果 根据我之前的post https stackoverflow com questions 8343894 aes encrypt with open
  • 使用 Selenium 测试 Sencha 2 应用程序

    我无法单击 Sencha 2 生成的按钮 因为它不是输入字段 它用 div 和 span 构建了按钮 找到这个链接 它描述了如何通过 Selenium 测试单击按钮http mobilewebqa blogspot com http mob
  • 如何获取 sqlalchemy 中受影响的行数?

    我有一个关于 Python 和 sqlalchemy 模块的问题 相当于什么cursor rowcount在 sqlalchemy Python 中 ResultProxy对象有一个rowcount https docs sqlalchem
  • 替换交叉过滤器数据,恢复维度和组

    我在用着dc js http dc js github io渲染数据集的漂亮气泡图 底层的 dc js 是交叉过滤器 https github com square crossfilter 我想使用来自服务器的新数据顺利刷新我的图表 这个问
  • 如何获取 Matplotlib 当前可用的所有字体的列表?

    例如当我想设置时font in matplotlib rc font font import matplotlib font manager matplotlib font manager findSystemFonts fontpaths
  • Spring-data-mongo无法使用构造函数实例化java.util.List

    Using spring data mongodb 1 5 4 and mongodb driver 3 4 2 我有课Hotel public class Hotel private String name private int pri
  • 如何计算数字的正确宽度(以像素为单位)?

    我有一个自定义控件 将来可能有用户可自定义的字体 缩放已经实现 我必须在两位数字下方填充一个矩形 形成以 10 为基数的数字 我对零个 一个或两个数字有不同的颜色 使用字体 Name Microsoft Sans Serif Size 16