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 がある場合、境界ボックスを接触させても実際の文字が接触することはありません。これは、2 つの文字が結合されている線の上部と下部に C があり、中央に O があるためです。

文字が確実に接触するようにしたい場合は、代わりにグリフ アウトライン データを取得し、グリフ 2 上のグリフ 1 の投影点を見つける巧妙なアルゴリズムを使用するか、単純な最小最大アルゴリズムを使用して 2 つを配置する必要があります。互いに隣り合って、それらを透明な色でラスタライズし、色付けされたピクセルのいずれかが本来よりも暗いかどうかを確認します。そうであれば、文字を距離 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 に答える