【发布时间】:2021-12-22 17:20:27
【问题描述】:
我有一些现有的 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 相同的宽度测量值的任何想法?
谢谢。
【问题讨论】:
-
你有没有渲染它们,看看它们的大小有多大不同?很可能不同的字体大小。
-
渲染图像并进行比较。您发布的只是四舍五入错误,两个图像都是 251 像素宽。除非使用抗锯齿。
System.Drawing.Graphics正在使用 Windows 默认值、算法、分辨率、字距调整、间距、边距等。它也可能受到用户设置的影响。如果不指定设备,将使用默认设备,这可能在库之间不同。 -
此外,9 点不是 12 像素。实际像素大小取决于图像分辨率 (DPI)。点是实际的物理尺寸,类似于英寸或厘米。打印 9 个点需要多少像素取决于设备的分辨率 - 与 4K 屏幕相比,用于在非高清屏幕上绘制相同字符串的像素更少。打印机可以在更高的分辨率下工作
-
查看Point (typography)
The DTP point is defined as 1⁄72 of an international inch ( 1 / 72 × 25.4 mm ≈ 0.353 mm) and, as with earlier American point sizes, is considered to be 1⁄12 of a pica.上的维基百科文章
标签: skiasharp .net-6.0 imagesharp system.drawing.common