skiasharp - 使用 C# 以跨平台方式测量字符串的宽度(以像素为单位)
问题描述
我有一些现有的 C# 代码,用于System.Drawing.Common
测量字符串的近似宽度(以像素为单位):
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))
{
// Size: 9 Points
using var font = new System.Drawing.Font(familyName: "Times New Roman", emSize: 9f);
var ms = graphics.MeasureString(text, font);
// Output: 'abc123 this is some long text my dog's name is fido.' via System.Drawing: 394.00195 x 22.183594
Console.WriteLine($"'{text}' via System.Drawing: {ms.Width} x {ms.Height}");
}
升级到 后.NET 6.0
,我收到一堆警告消息,告诉我这些图形基元仅在 Windows 上受支持。我希望这个测量可以在其他平台上工作,所以我尝试对两者做类似的事情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");
// Size: 12px
paint.TextSize = 12f;
var skBounds = SKRect.Empty;
var textWidth = paint.MeasureText(text.AsSpan(), ref skBounds);
// Output: 'abc123 this is some long text my dog's name is fido.' via SkiaSharp: 251.13867 x 12
Console.WriteLine($"'{text}' via SkiaSharp: {skBounds.Width} x {skBounds.Height}");
}
并且ImageSharp
:
var text = "abc123 this is some long text my dog's name is fido.";
// Size: 12px
var imgSharpFont = SixLabors.Fonts.SystemFonts.CreateFont("Times New Roman", 12f);
var imgSharpMeasurement = TextMeasurer.Measure(text, new RendererOptions(imgSharpFont));
// Output: 'abc123 this is some long text my dog's name is fido.' via ImageSharp: 251.13869 x 14.589844
Console.WriteLine($"'{text}' via ImageSharp: {imgSharpMeasurement.Width} x {imgSharpMeasurement.Height}");
但是,如您所见,我无法获得SkiaSharp
或ImageSharp
产生相同的宽度,尽管它们产生了相似的结果:
'abc123 this is some long text my dog's name is fido.' via System.Drawing: 394.00195
'abc123 this is some long text my dog's name is fido.' via SkiaSharp: 251.13867
'abc123 this is some long text my dog's name is fido.' via ImageSharp: 251.13869
我对图形编程的了解不足以知道我缺少什么。它可能是点和像素之间的单位转换,或者我没有设置正确的属性。关于如何进行SkiaSharp
和/或ImageSharp
返回与 相同的宽度测量的任何想法System.Drawing.Common
?
谢谢你。
解决方案
基本上问题是由于默认情况下System.Drawing.Graphics
将使用您机器的 DPI(原因是因为System.Drawing
它是围绕 GDI 构建的,GDI 是一个用于将图像绘制到屏幕和打印机的 Windows 子系统)。
这是反对ImageSharp
并SkiaSharp
默认为72 DPI。(我知道ImageSharp
肯定会,并且由于和之间的数字在SkiaSharp
彼此ImageSharp
的舍入误差内,它也必须使用 72 的 DPI)。
根据您提供的数字,我猜您正在运行 112 DPI 显示器?
推荐阅读
- java - 网络服务 java
- oracle - 如何将多个结果连接到oracle中的一列?
- c# - 如何使用按钮更改表单的背景颜色
- plot - 为什么 Mathematica 显示一个空白框?
- php - PHP Singleton 作为 HTTP 服务器中 HTTP 请求的回调
- python - Python:将数据从 excel 转换为饼图
- android - Firestore Stripe 错误“无法序列化对象。不支持序列化集合,请改用列表。”
- android - HttpURLConnection 间歇性返回错误代码 500
- scala - 使用不同的设置两次运行 sbt 任务
- node.js - 带有令牌的 PASSPORT GOOGLE OAUTH2