0

我真的很感谢任何比我有更多 PHP 经验的人的帮助。

我正在使用 PHP 生成紧密包装的文本图像。到目前为止,它是这样工作的:

  1. 首先,它生成 x 个字符的随机字符串。
  2. 然后它制作带有背景等的图像。
  3. 它将第一个字符放置在特定位置(大小随机化,旋转等)
  4. 然后它放置下一个字符,使其边界框的左下角与前一个字符的边界框的右下角位于同一点(加上一些随机性等)。代码如下:

    $coords = array();
    $pos_y = $this->image_height / 2;
    
    for ($counter = 0; $counter < $this->code_length; $counter++){
        $sbox = @imagettfbbox($size, $angle, $font, $this->code[$counter]);
        if($counter == 0)
            $pos_x = $this->image_width / $this->code_length;
        else
            // element 2 is the x co-ord of the bottom right corner of the ttf box
            $pos_x = $coords[$counter-1][2];
        @imagettftext($this->image, $size, $angle, 
             $pos_x, $pos_y, $fontcolor, $font, $this->code[$counter]);
    }
    
  5. 并为字符串中的每个后续字符重复 4。

我想要的是尽可能地让每个角色都接触到它的邻居。到目前为止,我所做的对于像“M”这样的字符来说效果很好,其中字形的底角或多或少位于边界框的角落,但对于像“G”或“I”这样的字母来说,它还差得远。

有谁知道获取 ttf 字形的实际尺寸而不仅仅是边界框的方法?或者有人能想出更好的方法来解决这个问题吗?

非常感谢任何想法/想法/建议。

4

1 回答 1

1

边界框就是这样 - 指示文本的最小/最大 x 和 y 值的框。如果你有字母 C 和字母 O,让它们的边界框接触永远不会使实际的字母接触,因为连接两个字母的线的顶部和底部是 C,中间是 O。

如果要确保字母接触,则必须获取字形轮廓数据,并且要么使用聪明的算法在字形 2 上找到字形 1 的投影点,要么使用天真的 minmax 算法将两者放在一起彼此相邻,用透明颜色对它们进行光栅化,看看是否有任何颜色的像素比应有的颜色深,如果是,将字母分开距离 D,再试一次,如果它们不重叠,则一起移回距离 D/2,如果它们重叠,再移出 D/4,如果不重叠,再移入 D/4,然后用 D/8、D/16 等纠正,直到距离小于一个像素。

边界框对齐既便宜又容易,不幸的是,您想要做的是,不能两者兼而有之。它可能很便宜(但算法很难)或容易(但算法很昂贵)。

(如果您想尝试使用字形轮廓数据,您可以尝试使用 FreeType2 或类似https://github.com/pomax/php-font-parser的东西)

于 2013-06-21T15:46:21.460 回答