SkiaSharp的measureText和系统绘图的measureText的区别

问题描述 投票:0回答:1

我正在尝试使用此代码找出 Windows 环境中字符的宽度和高度:

using(Graphics g = Graphics.FromImage(new Bitmap(800,550)))
{
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        SizeF size = g.MeasureString("0",new Font(FontFamily.GenericMonospace, 10) , new PointF(0, 0), 
            StringFormat.GenericTypographic);
        Console.WriteLine(size.Height);
        Console.WriteLine(size.Width);
}

输出为: 身高:15.104165 宽度:8.001301

我正在尝试使用以下代码将此过程移植到使用 SkiaSharp 的跨平台代码:

using (SKPaint p = new SKPaint
           {
               IsAntialias = true, Typeface = SKTypeface.FromFamilyName("monospace"),
               TextSize = 10
           })
    {
            string text = "0" ;
            SKRect textBounds = SKRect.Empty;
            p.Color = SKColors.Black;
            p.Style = SKPaintStyle.Fill;
            p.MeasureText(text, ref textBounds);
            Console.WriteLine(textBounds.Height);
            Console.WriteLine(textBounds.Width);
    }

这是 SkiaSharp 中同一字符的高度和宽度: 身高:7 宽度:5

我可以得到一些关于这方面的帮助吗? 我错过了什么?

c# cross-platform system.drawing skiasharp
1个回答
0
投票

这就是我在给定字体大小(以 pt 为单位)的情况下用

System.Drawing
:

测量文本(以毫米为单位)的方法
static double PtToMm(double pt) { return pt * 25.4 / 72.0; }

var familyName = "Arial";
var fontHeightPt = 10.0f;

using var font = new Font(familyName, fontHeightPt, FontStyle.Regular, GraphicsUnit.World);
using var graphicsImage = new Bitmap(1, 1);
graphicsImage.SetResolution(300.0f, 300.0f);
using var graphics = Graphics.FromImage(graphicsImage);
using var stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
// System.Drawing doesn't measure trailing whitespace on default
// stringFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
var nullPoint = new PointF(0, 0);

var textBounds = graphics.MeasureString(text, font, nullPoint, stringFormat);
var totalWidthMm = PtToMm(textBounds.Width);
var totalHeightMm = PtToMm(textBounds.Height);

使用 SkiaSharp,一切都有点不同。这是我当前的解决方案:

using var fontManager = SKFontManager.CreateDefault();
using var typeface = fontManager.MatchFamily(familyName, SKFontStyle.Normal);

using var fontPaint = new SKPaint
{
  IsAntialias = true,
  HintingLevel = SKPaintHinting.Normal,
  TextAlign = SKTextAlign.Left,
  TextSize = (float)PtToMm(fontHeightPt),
  Typeface = typeface,
};
var textBounds = new SKRect();
var totalWidthMm = fontPaint.MeasureText(Text, ref textBounds);
var totalHeightMm = textBounds.Height;

// textBounds.Width => width of text without leading/trailing whitespace
// textBounds.Left => width of leading whitespace

如果您想测量带前导但不带尾随空格的文本:

var totalWidthMm = fontPaint.MeasureText(Text.AsSpan().TrimEnd(), ref textBounds);
© www.soinside.com 2019 - 2024. All rights reserved.