我在我们的 blazor 应用程序中使用 svg 元素。因为我在 Svg 中使用文本元素。同时我需要文本元素的高度和宽度(以像素为单位)。基于此,我正在对 SVG 元素进行一些尺寸更改。不幸的是,我不知道如何获取文本元素的大小。
在 ASP.Net 应用程序中,有如下方式,
using System.Drawing;
private float GetWidthOfString(string str)
{
Bitmap objBitmap = default(Bitmap);
Graphics objGraphics = default(Graphics);
objBitmap = new Bitmap(500, 200);
objGraphics = Graphics.FromImage(objBitmap);
SizeF stringSize = objGraphics.MeasureString(str, new Font("Arial", 12));
objBitmap.Dispose();
objGraphics.Dispose();
return stringSize.Width;
}
Run Code Online (Sandbox Code Playgroud)
但我不能在 blazor 应用程序中使用它。有没有办法以像素为单位找到文本元素的大小?
在 Blazor 中获取图形信息的最简单方法是使用 DOM。
通过创建临时 svg 元素,使用 javascript 测量文本。
在您的 JavaScript 中,创建以下函数:
window.measureString = function(textParams) {
const svg = `
<svg style="position:absolute">
<text
font-family="${textParams.Font}"
font-size="${textParams.Size}">
${textParams.Text}
</text>
</svg>`;
const el = document.createElement("div");
el.innerHTML = svg;
document.body.appendChild(el);
const svgText = el.querySelector('text').getBBox();
el.remove();
return { Height: svgText.height, Width: svgText.width };
}
Run Code Online (Sandbox Code Playgroud)
...以及与该功能的互操作。
在你的.blazor文件中:
@inject IJsInterop js;
@code {
public class Measurement { public decimal Width { get;set; } public decimal Height { get;set; }}
Task MeasureString(string text, string font, int size) {
var measurement = await js.InvokeAsync<Measurement>("measureString",
new {
Text = text,
Font = font,
Size = size
});
Console.WriteLine($"Width: {measurement.Width} Height: {measurement.Height}";
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是2ms每次调用的平均值。
出于好奇,我还找到了一种使用库对本机 c# 进行(或多或少)相同测量的方法SixLabors.Fonts。
以下代码可让您进行测量。字体本身必须首先作为 提供Stream,因此工作量很大。此外,测量不会产生与上面的 js 代码相同的结果,因此可能与 SVG 测量不兼容。我C:\Windows\Fonts\Arial.ttf用作MemoryStream.
using SixLabors.Fonts;
var fontStream = GetFontAsMemoryStream();
var fonts = new FontCollection();
var font = fonts.Install(fontStream);
var renderOption = new RendererOptions(font.CreateFont(size));
var measurement = TextMeasurer.Measure(text, renderOption);
Run Code Online (Sandbox Code Playgroud)
上面的代码平均为2500ms,所以比 js interop 慢了 1000 多倍。也许可以以某种方式缓存结果fonts.Install(),但我没有立即成功地无例外地重新使用该font实例。
| 归档时间: |
|
| 查看次数: |
657 次 |
| 最近记录: |