代码之家  ›  专栏  ›  技术社区  ›  Jonathan Feinberg

在actionscript中有没有一种方法可以获得字形的实际边界框?

  •  2
  • Jonathan Feinberg  · 技术社区  · 15 年前

    我正在学习actionscript/flash。我喜欢玩文本,并且用出色的Java2dAPI做了很多这样的事情。

    我想知道的一件事是,“你到底在哪里画这个字形?”textfield类提供了 getBounds getCharBoundaries 但这些方法返回的矩形分别远远超出了整个文本对象或单个字符的实际边界。

    var b:Sprite = new Sprite();
    b.graphics.lineStyle(1,0xFF0000);
    var r:Rectangle = text.getCharBoundaries(4);
    r.offset(text.x, text.y);
    b.graphics.drawRect(r.x,r.y,r.width,r.height);
    addChild(b);
    
    b = new Sprite();
    b.graphics.lineStyle(1,0x00FF00);
    r = text.getBounds(this);
    b.graphics.drawRect(r.x,r.y,r.width,r.height);
    addChild(b);
    

    some bounds

    有没有什么方法可以获得关于ActionScript中文本glyph的实际可视界限的更精确信息?

    3 回复  |  直到 8 年前
        1
  •  2
  •   Cory Petosky    15 年前

    在flash 9中不太可能——Richard的答案是一个巧妙的解决方案,尽管可能完全不适合生产代码(如他所提到的):)

    如果您可以使用Flash 10,请查看新的 text engine classes ,尤其是文本行。

        2
  •  3
  •   Cay    15 年前

    Richard在正确的轨道上,但是bitmapdata.getcolorbounds()更快更准确…我已经用过几次了,并且针对您的特定需求进行了优化,它不像人们想象的那么慢。

    Cory关于使用flash.text.engine的建议可能是正确的,但我警告您flash.text.engine非常(非常!)与textfield相比,很难使用。

        3
  •  2
  •   richardolsson    8 年前

    恐怕在textfield上可用的所有方法都应该做您已经发现它们要做的事情。除非性能是应用程序中的关键(即,除非您经常这样做),否则可能有一个选项是将文本字段绘制到位图数据中,并在getHarboundaries()检索到的边界框中找到最顶部、最左侧的ET C颜色像素?

    var i : int;
    var rect : Rectangle;
    var top_left : Point;
    var btm_right : Point;
    
    var bmp : BitmapData = new BitmapData(tf.width, tf.height, false, 0xffffff);
    bmp.draw(tf);
    
    rect = tf.getCharBoundaries(4);
    top_left = new Point(Infinity, Infinity);
    btm_right = new Point(-Infinity, -Infinity);
    
    for (i=rect.x; i<rect.right; i++) {
      var j : int;
    
      for (j=rect.y; j<rect.bottom; j++) {
        var px : uint = bmp.getPixel(i, j);
    
        // Check if pixel is black, i.e. belongs to glyph, and if so, whether it
        // extends the previous bounds
        if (px == 0) {
          top_left.x = Math.min(top_left.x, i);
          top_left.y = Math.min(top_left.y, j);
          btm_right.x = Math.max(btm_right.x, i);
          btm_right.y = Math.max(btm_right.y, j);
        }
      }
    }
    
    var actualRect : Rectangle = new Rectangle(top_left.x, top_left.y);
    actualRect.width = btm_right.x - top_left.x;
    actualRect.height = btm_right.y - top_left.y;
    

    此代码应该循环遍历getchaboundaries()认为是glyph矩形一部分的所有像素。如果一个像素不是黑色的,它会被丢弃。如果为黑色,代码将检查像素是否比以前在循环中检查过的任何像素向上、向下、向右或向左扩展。

    显然,这不是最佳代码,带有嵌套循环和不必要的点对象。尽管如此,希望代码足够可读,并且您能够找出最容易优化的部分。

    您可能还需要引入一些阈值,而不是忽略任何不是变黑的像素。