题
这是一个长枪,但没有人知道的一个算法,用于估计和分类文本的宽度(变量宽字体)基础上,其内容是什么?
例如,我想知道 iiiiiiii 是不一样宽 abcdefgh, ,而这又是不一样宽 WWWWWWWW, 虽然所有三个字符串八个字符长。
这实际上是试图建立一些智慧成一串截断的方法,这在目前是正确的截断视广串的,但也是不必要的截断视的狭窄串的,因为这两个字符串中含有的相同数字。它可能是足够的算法来分类输入字符串 狭窄, 正常的 或 宽 然后截断为合适。
这个问题真的不是特定语言,但如果有一个算法则我会实现它。这是一个网络应用程序。我知道,有答案,以便处理这个问题使用JavaScript获得宽度的一个含有 div
元,但我想知道,如果一个服务器的端解决方案是可能的。
解决方案
大多数GUI框架提供了一些计算给定输出设备上字体的文本度量的方法。
例如,使用 java.awt.FontMetrics
,我相信你可以这样做:
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
public int measureText(Graphics g, String text) {
g.setFont(new Font("TimesRoman", Font.PLAIN, 12));
FontMetrics metrics = g.getFontMetrics();
return metrics.stringWidth(text);
}
未经测试,但您明白了。
在.Net下,您可以使用 Graphics .MeasureString
方法。在C#中:
private void MeasureStringMin(PaintEventArgs e)
{
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}
其他提示
这对我有用:
AffineTransform af = new AffineTransform();
FontRenderContext fr = new FontRenderContext(af,true,true);
Font f = new Font("Arial", 0, 10); // use exact font
double width= f.getStringBounds("my string", fr).getWidth();
对于Web应用程序,您无法(真正)获得正确的估算。不同的字体具有不同的宽度,因此这不仅取决于客户端(浏览器)及其缩放和DPI设置,还取决于该计算机(和操作系统)上存在的字体或其替换。
如果您需要精确测量,请创建一个图形(位图,SVG,甚至某些PDF或其他),这些图形将在服务器上而不是在客户端上进行布局和渲染。
没有可靠的服务器端解决方案来计算文本宽度。(在创建文本图像之外,可能还有SVG)
如果您尝试使用浏览器镜头等工具并在相对基本的页面上运行它,您将立即明白为什么。很难预测即使最平凡的例子会变得多么广泛,更不用说如果用户决定放大浏览器等......
没有准确地说明你可能想要截断字符串(它可能有助于提供潜在的解决方案),但常见的是因为你想在某个点切断文本并提供一个椭圆。
你真的没有办法知道什么浏览器,字体设置,屏幕的大小等客户使用。(OK,有时请求头提供指示,但真的没有一致或可靠。)
因此,我将:
- 显示一些样本案文在因特网浏览器默认设置一个视窗的大小1024×768(这通常是最常见的大小)
- 采取的平均符/线路,与此配置和使用,对于您的估计。
我通常会发现这样的"足够好的",例如,估计线路的数量,一些文字将在一浏览器,以估计有多少广告,以显示接下来的文本。
如果这是真的真的很重要给你,然后我可以想象一下,一个令人费解的方案,借此你最初发送一些Javascript的客户,那么需要测量并把它送回你的服务器,然后使用该信息,为未来的网页。我不能想象它的通常价值的努力,虽然。
我想你应该选择一些方案:
- 确切的解决方案:总的宽度为每个字符串中(大多数Api会给你这个信息)
- 快速估计:或者采取最大或最小宽度和乘它的数字。
当然,一些混合的估计是可能的,但我认为这是太多的精力在错误的方向。
对于一个不错的*客户端解决方案,你可以尝试一种混合的CSS-and-Javascript方法,如 RichieHindle对我的问题的回答。
鉴于您不知道用户将在哪个字体中看到该页面(它们总是可以覆盖您的选择,Ctrl- +页面等),“正确”等等。这样做的地方是在浏览器上...虽然浏览器不容易!
*
当我说“好”时,我的意思是“可能很好,但我还没有真正尝试过”。
这实际上是尝试将一些智能构建成字符串截断方法[...]
真的值得努力吗?我们遇到了这个问题。这是跨语言的。修复是保持原样。保持这种智能的复杂性随着您添加支持的每种语言而迅速(并且可能呈指数级)增加。因此我们的决定。
[...]根据内容估算和分类文本宽度(可变宽度字体)的算法?
大多数字体库都会为您提供此信息。但这是相当低级的东西。基本思想是传入一个字符串并以磅为单位返回宽度。