C# 跨平台测量字符串像素宽度并匹配System.Drawing.Common结果
问题根因
测量结果差异来自两个核心配置不匹配:
System.Drawing.Common的Graphics.MeasureString默认使用兼容GDI的排版规则,会在字符串前后额外添加约1/6em的留白用于字符悬挂,同时默认开启字符间距适配,并非纯粹的字符边界宽度- SkiaSharp、ImageSharp默认使用印刷业标准的紧凑测量规则,仅计算字符本身的实际占用宽度,没有额外留白
如果你可以调整原有System.Drawing的测量逻辑,直接添加StringFormat.GenericTypographic参数即可让输出和两个跨平台库的251px左右结果对齐,代码示例:
var text = "abc123 this is some long text my dog's name is fido."; using (var bitmap = new Bitmap(500, 50)) using (var graphics = Graphics.FromImage(bitmap)) { using var font = new System.Drawing.Font(familyName: "Times New Roman", emSize: 9f); // 增加这一行使用标准印刷排版规则,去掉额外留白 var format = StringFormat.GenericTypographic; var ms = graphics.MeasureString(text, font, int.MaxValue, format); Console.WriteLine($"'{text}' via System.Drawing: {ms.Width} x {ms.Height}"); }
如果你必须让跨平台库匹配原有System.Drawing的默认394px左右的输出结果,可分别调整两个库的配置:
SkiaSharp 适配方案
var text = "abc123 this is some long text my dog's name is fido."; using (var paint = new SKPaint()) { paint.Typeface = SKTypeface.FromFamilyName("Times New Roman"); paint.TextSize = 12f; // 9磅=9*96DPI/72=12px,该换算规则正确 paint.TextAlign = SKTextAlign.Left; paint.HintingLevel = SKHintingLevel.Full; // 模拟GDI+默认添加的前后留白:左右各加1/6em的宽度 var em = paint.TextSize / paint.Typeface.UnitsPerEm * paint.Typeface.CapHeight; var extraPadding = em / 6 * 2; var skBounds = SKRect.Empty; paint.MeasureText(text.AsSpan(), ref skBounds); // 补充留白后得到与原System.Drawing一致的宽度 var finalWidth = skBounds.Width + extraPadding; Console.WriteLine($"'{text}' via SkiaSharp: {finalWidth} x {skBounds.Height}"); }
ImageSharp 适配方案
var text = "abc123 this is some long text my dog's name is fido."; var imgSharpFont = SixLabors.Fonts.SystemFonts.CreateFont("Times New Roman", 12f); // 配置GDI兼容排版模式 var options = new RendererOptions(imgSharpFont) { ApplyKerning = true, DpiX = 96, DpiY = 96, TextLayoutMode = TextLayoutMode.Gdi }; var imgSharpMeasurement = TextMeasurer.Measure(text, options); Console.WriteLine($"'{text}' via ImageSharp: {imgSharpMeasurement.Width} x {imgSharpMeasurement.Height}");
内容的提问来源于stack exchange,提问作者Jon Sagara
相关产品推荐
相关产品推荐

