首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >安卓画图:.measureText() vs .getTextBounds()

安卓画图:.measureText() vs .getTextBounds()
EN

Stack Overflow用户
提问于 2011-09-26 06:57:56
回答 4查看 107.4K关注 0票数 194

我使用Paint.getTextBounds()测量文本,因为我对获得要呈现的文本的高度和宽度很感兴趣。但是,呈现的实际文本总是比getTextBounds()填充的Rect信息的.width()宽一点。

令我惊讶的是,我测试了.measureText(),发现它返回了一个不同的(更高的)值。我试了试,发现它是正确的。

为什么它们会报告不同的宽度?如何正确获取高度和宽度?我的意思是,我可以使用.measureText(),但是我不知道是否应该信任getTextBounds()返回的.height()

按照要求,以下是重现该问题的最小代码:

代码语言:javascript
复制
final String someText = "Hello. I believe I'm some text!";

Paint p = new Paint();
Rect bounds = new Rect();

for (float f = 10; f < 40; f += 1f) {
    p.setTextSize(f);

    p.getTextBounds(someText, 0, someText.length(), bounds);

    Log.d("Test", String.format(
        "Size %f, measureText %f, getTextBounds %d",
        f,
        p.measureText(someText),
        bounds.width())
    );
}

输出显示,差异不仅大于1(并且不是最后一分钟的舍入误差),而且似乎随着大小的增加而增加(我正要得出更多结论,但它可能完全取决于字体):

代码语言:javascript
复制
D/Test    (  607): Size 10.000000, measureText 135.000000, getTextBounds 134
D/Test    (  607): Size 11.000000, measureText 149.000000, getTextBounds 148
D/Test    (  607): Size 12.000000, measureText 156.000000, getTextBounds 155
D/Test    (  607): Size 13.000000, measureText 171.000000, getTextBounds 169
D/Test    (  607): Size 14.000000, measureText 195.000000, getTextBounds 193
D/Test    (  607): Size 15.000000, measureText 201.000000, getTextBounds 199
D/Test    (  607): Size 16.000000, measureText 211.000000, getTextBounds 210
D/Test    (  607): Size 17.000000, measureText 225.000000, getTextBounds 223
D/Test    (  607): Size 18.000000, measureText 245.000000, getTextBounds 243
D/Test    (  607): Size 19.000000, measureText 251.000000, getTextBounds 249
D/Test    (  607): Size 20.000000, measureText 269.000000, getTextBounds 267
D/Test    (  607): Size 21.000000, measureText 275.000000, getTextBounds 272
D/Test    (  607): Size 22.000000, measureText 297.000000, getTextBounds 294
D/Test    (  607): Size 23.000000, measureText 305.000000, getTextBounds 302
D/Test    (  607): Size 24.000000, measureText 319.000000, getTextBounds 316
D/Test    (  607): Size 25.000000, measureText 330.000000, getTextBounds 326
D/Test    (  607): Size 26.000000, measureText 349.000000, getTextBounds 346
D/Test    (  607): Size 27.000000, measureText 357.000000, getTextBounds 354
D/Test    (  607): Size 28.000000, measureText 369.000000, getTextBounds 365
D/Test    (  607): Size 29.000000, measureText 396.000000, getTextBounds 392
D/Test    (  607): Size 30.000000, measureText 401.000000, getTextBounds 397
D/Test    (  607): Size 31.000000, measureText 418.000000, getTextBounds 414
D/Test    (  607): Size 32.000000, measureText 423.000000, getTextBounds 418
D/Test    (  607): Size 33.000000, measureText 446.000000, getTextBounds 441
D/Test    (  607): Size 34.000000, measureText 455.000000, getTextBounds 450
D/Test    (  607): Size 35.000000, measureText 468.000000, getTextBounds 463
D/Test    (  607): Size 36.000000, measureText 474.000000, getTextBounds 469
D/Test    (  607): Size 37.000000, measureText 500.000000, getTextBounds 495
D/Test    (  607): Size 38.000000, measureText 506.000000, getTextBounds 501
D/Test    (  607): Size 39.000000, measureText 521.000000, getTextBounds 515
EN

回答 4

Stack Overflow用户

发布于 2011-10-04 12:27:29

我的经验是,getTextBounds将返回封装文本的绝对最小边界矩形,而不一定是渲染时使用的测量宽度。我还想说,measureText假设有一行。

为了获得准确的测量结果,您应该使用StaticLayout呈现文本并提取测量结果。

例如:

代码语言:javascript
复制
String text = "text";
TextPaint textPaint = textView.getPaint();
int boundedWidth = 1000;

StaticLayout layout = new StaticLayout(text, textPaint, boundedWidth , Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
int height = layout.getHeight();
票数 22
EN

Stack Overflow用户

发布于 2012-06-01 23:43:32

很抱歉再次回答这个问题...我需要嵌入图像。

我认为@mice发现的结果具有误导性。当字体大小为60时,观察结果可能是正确的,但当文本较小时,它们会变得更加不同。例如:10px。在这种情况下,文本实际上是超出边界绘制的。

截图的源码:

代码语言:javascript
复制
  @Override
  protected void onDraw( Canvas canvas ) {
    for( int i = 0; i < 20; i++ ) {
      int startSize = 10;
      int curSize = i + startSize;
      paint.setTextSize( curSize );
      String text = i + startSize + " - " + TEXT_SNIPPET;
      Rect bounds = new Rect();
      paint.getTextBounds( text, 0, text.length(), bounds );
      float top = STEP_DISTANCE * i + curSize;
      bounds.top += top;
      bounds.bottom += top;
      canvas.drawRect( bounds, bgPaint );
      canvas.drawText( text, 0, STEP_DISTANCE * i + curSize, paint );
    }
  }
票数 11
EN

Stack Overflow用户

发布于 2014-08-12 17:05:49

还有另一种方法可以精确地测量文本边界,首先您应该获取当前绘制和文本的路径。在您的示例中,应该是这样的:

代码语言:javascript
复制
p.getTextPath(someText, 0, someText.length(), 0.0f, 0.0f, mPath);

在此之后,您可以调用:

代码语言:javascript
复制
mPath.computeBounds(mBoundsPath, true);

在我的代码中,它总是返回正确的期望值。但是,不确定它是否比你的方法更快。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7549182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档