Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 图形的奇怪行为。不同分辨率下的测量_C#_.net_Graphics_Gdi+_Resolution - Fatal编程技术网

C# 图形的奇怪行为。不同分辨率下的测量

C# 图形的奇怪行为。不同分辨率下的测量,c#,.net,graphics,gdi+,resolution,C#,.net,Graphics,Gdi+,Resolution,我注意到图形的奇怪行为。在不同的分辨率下测量 对于默认分辨率(96x96),我测试的不同字体大小之间存在线性关系 但是,如果我将其提高到512 x 512,线性关系就会消失,并且在使用度量字符串时会发生一些非常奇怪的事情。(见下面4幅图) 如果我将图形对象的分辨率保留为默认大小,并测量字体大小,则字体大小与字符串宽度之间的关系如下: 图形对象,默认分辨率(96): 字体大小(X轴)、特定字符串的宽度(Y轴) 字体大小(X轴)、特定字符串的高度(Y轴) 但是,如果我改变决议 图形对象,512分

我注意到图形的奇怪行为。在不同的分辨率下测量

对于默认分辨率(96x96),我测试的不同字体大小之间存在线性关系

但是,如果我将其提高到512 x 512,线性关系就会消失,并且在使用度量字符串时会发生一些非常奇怪的事情。(见下面4幅图)

如果我将图形对象的分辨率保留为默认大小,并测量字体大小,则字体大小与字符串宽度之间的关系如下:

图形对象,默认分辨率(96):

字体大小(X轴)、特定字符串的宽度(Y轴)

字体大小(X轴)、特定字符串的高度(Y轴)

但是,如果我改变决议

图形对象,512分辨率:

字体大小(X轴)、特定字符串的宽度(Y轴)

字体大小(X轴)、特定字符串的高度(Y轴)

有人知道为什么会这样吗

谢谢你

应该注意的是,我使用的是.NET4(完整配置文件)

用于生成图形的代码(更改每种类型的分辨率):


这个答案只是猜测,但证据完全符合

你看到的是绳子被缠绕在两条线上

让我们假设如下:

  • 文本的宽度与字体大小成线性比例
  • 文本的高度与字体大小成线性比例
  • 这符合512分辨率图形的开始,所有内容都线性增加

    在某些情况下,宽度会急剧减少一定量,同时高度会加倍

    这意味着一个单词被移到了第2行,这使高度增加了一倍(2行与之前的1行相比),并且字符串的宽度减少了一定量,因为行上的最后一个单词现在位于第2行的开头

    从那时起,宽度再次缓慢增加,因为仍在第1行的字符串部分随着字体大小的增加而线性变宽。同时,高度线性增加,但现在的速度是中断前的两倍,因为现在有两行比之前的1行高

    在某一点上,第1行的最后一个单词再次打破了最大宽度,并在第2行上向下移动,在之前单独存在的单词之前,在这一点上,宽度再次急剧减少了一定量


    如果你继续你的图表,我预测宽度将继续它当前的模式。它每次向下倾斜的确切量与移动的单词的宽度成正比。同时,在某个时刻,第二条线将需要断开,在这种情况下,您将获得3倍的高度,然后高度将以3倍的速度增加,以此类推。

    我相信这可能是由于GDI+中的暗示/网格拟合算法造成的。就字形易读性而言,测试中的字体大小非常小,因此,渲染引擎尝试对每个字形应用特殊转换以使其更清晰。这些转换在很大程度上取决于目标DPI

    还值得一提的是,字体大小的大幅增加将导致更“线性”的依赖性

    这将通过一些示例更详细地解释这些机制


    同时,您可以尝试修改
    Graphics.TextRenderingHint
    属性和/或尝试
    TextRenderer
    而不是
    Graphics.DrawString
    ,如果这有助于解决您的问题。

    Graphics.MeasureString()非常不稳定,在.NET版本2中被TextRenderer.MeasureText()取代。否则,您可能会从TrueType暗示算法中看到这种模式。在点或像素大小小于8的情况下渲染文本是毫无意义的。当宽度达到850时,它开始“结巴”。这是我输入Graphics.MeasureString的最大允许宽度。正如Lasse V.Karlsen指出的,该死的事情是包装。我未能添加“不换行”标志。谢谢大家!虽然我还没有证实这一点——从我的图上看,这似乎是合乎逻辑的,因为当字符串宽度达到850时,“口吃”就会发生——这正是我输入Graphics.MeasureString的允许宽度。非常感谢。我本应该抓住这一点,我责怪阅读到凌晨3点:德威尔,请确认一下:)这里的其他答案告诉我,我对文本渲染和.NET的了解没有我想了解的一半,所以我可能在这里遗漏了一些东西。尽管如此,这似乎是合适的:)这是因为缺少NoWrap标志。事实上,口吃总是发生在850点,这是一个确凿的事实。我确认了。非常感谢。谢谢你的提示。我将来也会关注这一点。
    string str = "6  CN-3 Tie EomgVeo405- 2ss>era09rni IBne 20iopv Atdrsn - Ng72";
    SizeF sizef = new SizeF(855, 14.000001f);
    StringFormat stringFormat = new StringFormat() 
    {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Near,
        Trimming = StringTrimming.None,
        FormatFlags = StringFormatFlags.NoClip,
    };
    
    Bitmap b = new Bitmap(901, 401);
    //b.SetResolution(512, 512);
    Graphics g = Graphics.FromImage(b);
    
    for (float x = origFont.Size; x >= 0.5; x -= 0.1f)
    {
        var data = g.MeasureString(str, new Font("Microsoft Sans Serif", x), sizef, stringFormat);
        Console.WriteLine(x + "\t" + data.Width + "\t" + data.Height);
    }