画像処理は多くのプログラムの機能の 1 つであり、テキスト レンダリングは描画の基本コンポーネントです。 PHP は、多くの拡張ライブラリを通じて画像処理をサポートしています。最も一般的に使用されているのは、一連の imagexxx() 関数を通じて描画機能を提供する GD ライブラリです。この記事では、テキストの描画という非常に小さな点に焦点を当てます。 Win32 に詳しい人なら、TextOut() であらゆるテキストを簡単に表示できることを知っていますが、PHP の世界では、簡単ではないことがあります。 1 imageTtfText() 関数の詳細な説明
PHP 描画の初心者にとって、最初に遭遇する問題は、imageString() 関数が漢字の描画をサポートしていないことです。これは初心者にとっては面と向かって平手打ちされることがよくありますが、UTF-8 でエンコードされた文字列を描画できる imageTtfText() 関数もあり、もちろん中国語の文字も描画できるため、心配する必要はありません。ただし、それを使用するのはそれほど簡単ではありません。まずそのプロトタイプステートメントを見てみましょう:
パラメータは全部で 8 つあり、すべて必須ですが、公式ドキュメントでのこれらのパラメータの説明は十分ではありません。ここで、著者はより詳細かつ明確になるよう最善を尽くしています 説明:
(1)$image これはキャンバス リソースです。説明する必要はありません
(2)$size、公式ドキュメントでは次のように説明されています。フォント サイズとその長さの単位は GD ライブラリのバージョンによって異なります。GD1 の場合はピクセル、GD2 の場合はポイントです。最近はGD2が一般的ですが、このポンドは何を意味するのでしょうか?これにはフォント デザインの基本が含まれます。
簡単に言えば、ポンドは長さの単位です。1 インチを 72 等分した場合、各部分は 1 ポンドになります。ここで強調しなければならないのは、ポンドは絶対的な物理単位であり、表示デバイスとは何の関係もないということです。
ピクセルについてはどうでしょうか?ピクセルのサイズは固定されていませんが、解像度に関係します。たとえば、iPhone Retina 画面のピクセルのサイズは、通常の LCD ディスプレイのピクセルのサイズよりもはるかに小さくなります。ただし、最小コンポーネントがピクセルであり、それ自体が各ピクセルのカラー値によって定義される単純なビットマップ イメージなど、解像度の概念を持たないものもあります。同じ画像を異なる解像度のモニターに表示すると、サイズも異なります。
ビットマップを操作する場合、ピクセル単位が最も正確で合理的です。それでは、GD2 ライブラリを使用する場合、20 ピクセルのサイズで単語を描画するにはどうすればよいでしょうか。つまり、20 ピクセルは何ポンドに相当しますか?これは解像度を通じて計算する必要がありますが、問題はビットマップ自体に解像度の概念がないことです。
さて、$size=20 ポイントが与えられた場合、描画が完了したときに imageTtfText() が占有するピクセルは何ピクセルになるかという質問に戻ります。いずれの場合も、imageTtfText() は最終的に特定のビットマップ ピクセル上にテキスト描画を実装します。
1 ポンド = PPI/72 ピクセル
この問題は確かに非常に複雑で、この関数はレンダリングされたピクセル領域を計算するために内部で特定の解像度 PPI を使用する必要があります。 GD2 ライブラリには、ユーザーがこの解像度を設定または読み取る方法は提供されていません。そうなると、手作業でテストするしかなくなります。さまざまなポイント サイズを使用してテキストを描画し、次の式を使用してテキストが占めるピクセルを測定します:
PPI = (72*ピクセル数)/ポイント サイズ。実験から得られた結論は次のとおりです:
1磅==>4像素, PPI=2882磅==>5像素, PPI=1803磅==>7像素, PPI=1684磅==>8像素, PPI=1445磅==>9像素, PPI=129.66磅==>10像素, PPI=1207磅==>11像素, PPI=113.142857142868磅==>12像素, PPI=1089磅==>14像素, PPI=11210磅==>15像素, PPI=10811磅==>16像素, PPI=104.7272727272712磅==>17像素, PPI=10213磅==>18像素, PPI=99.69230769230814磅==>19像素, PPI=97.71428571428615磅==>21像素, PPI=100.816磅==>22像素, PPI=9917磅==>23像素, PPI=97.41176470588218磅==>25像素, PPI=10019磅==>26像素, PPI=98.52631578947420磅==>27像素, PPI=97.221磅==>28像素, PPI=9622磅==>29像素, PPI=94.90909090909123磅==>30像素, PPI=93.91304347826124磅==>32像素, PPI=9625磅==>33像素, PPI=95.0426磅==>34像素, PPI=94.15384615384627磅==>35像素, PPI=93.33333333333328磅==>36像素, PPI=92.57142857142929磅==>38像素, PPI=94.34482758620730磅==>39像素, PPI=93.631磅==>40像素, PPI=92.90322580645232磅==>41像素, PPI=92.2533磅==>43像素, PPI=93.81818181818234磅==>44像素, PPI=93.17647058823535磅==>46像素, PPI=94.62857142857136磅==>47像素, PPI=9437磅==>48像素, PPI=93.40540540540538磅==>48像素, PPI=90.94736842105339磅==>50像素, PPI=92.30769230769240磅==>51像素, PPI=91.841磅==>52像素, PPI=91.31707317073242磅==>53像素, PPI=90.85714285714343磅==>55像素, PPI=92.09302325581444磅==>56像素, PPI=91.63636363636445磅==>57像素, PPI=91.246磅==>58像素, PPI=90.78260869565247磅==>60像素, PPI=91.91489361702148磅==>62像素, PPI=9349磅==>63像素, PPI=92.57142857142950磅==>63像素, PPI=90.7251磅==>64像素, PPI=90.35294117647152磅==>67像素, PPI=92.76923076923153磅==>68像素, PPI=92.37735849056654磅==>69像素, PPI=9255磅==>70像素, PPI=91.63636363636456磅==>71像素, PPI=91.28571428571457磅==>72像素, PPI=90.94736842105358磅==>74像素, PPI=91.86206896551759磅==>75像素, PPI=91.52542372881460磅==>76像素, PPI=91.261磅==>77像素, PPI=90.88524590163962磅==>78像素, PPI=90.5806451612963磅==>79像素, PPI=90.28571428571464磅==>81像素, PPI=91.12565磅==>83像素, PPI=91.93846153846266磅==>84像素, PPI=91.63636363636467磅==>85像素, PPI=91.3432835820968磅==>86像素, PPI=91.05882352941269磅==>86像素, PPI=89.73913043478370磅==>88像素, PPI=90.51428571428671磅==>90像素, PPI=91.26760563380372磅==>91像素, PPI=9173磅==>92像素, PPI=90.73972602739774磅==>93像素, PPI=90.486486486486
したがって、20 ピクセルのサイズでフォントを描画したい場合は、$size パラメーターを 14.5 ポイントに設定する必要があります。
$size は、フォントの表示サイズに正確に対応していないことにも注意してください。これは、異なる文字が同じ $size に対して同じスペースを占有するわけではないためです。たとえば、「国」という漢字の幅は、数字の 1 の幅よりもはるかに大きくなります。これは特に句読点に当てはまります。また、半角記号と全角記号も異なります。
つまり、imageTtfText() を使ってピクセルレベルまで正確に制御することは、大まかにしかできません。これはベクター フォントの小さな欠点でもあります。
(3) $angle は回転角度です。こちらの公式サイトでは非常に分かりやすく解説されており、説明が必要な点は2つあります。1つ目は角度の単位がラジアンではなく度であること、2つ目は回転の中心点がパラメータ$x、$yであることです。
(4)(5)$x, $y 描画された文字列の最初の文字のベースラインポイント。単位はピクセルです。これには、フォント デザインの基本知識であるベースラインが含まれます。この点は決して左上隅ではありませんが、それが何であるかは、使用されるフォントのデザインによって異なります。 Song Ti、Kai Ti、Hei Ti などの一般的なフォントの漢字の場合、このポイントはおおよそフォントの左下部分に位置しますが、英語の文字や句読点の場合は異なります。以下に示すように:
フォントの色、あまりありません説明。
(7) $fontfile
フォント ファイル。つまり、通常のフォント ファイル simkai.ttf などの TrueType フォント テンプレートを含むファイルです。このファイルの形式は標準化されており、プラットフォームに依存しません。したがって、Windows システムのフォント ファイルを Linux に直接コピーして使用できます。
(8)$text
2 ちょっとしたヒント
この機能は文字列を表示することはできますが、ワープロソフト(Word など)では使用できません。一度問題が発生するとこの機能は使用できなくなるためです。単語の間隔を扱うことができないため、当然ながら分散配置などの機能は実装できません。各行の「先頭と末尾を避ける」という要件 (たとえば、行の先頭に置くことはできません) と相まって、優れた文書処理を行うのは簡単ではありません。
回避策は、まず複雑な数式を通じて各文字の正確な位置を計算し、次に各文字に対してこの関数を呼び出します。
太字フォントが含まれるフォントファイルについては、太字フォントファイルを使用すれば問題ありません。問題は、多くのフォント ファイルが太字専用に設計されていないことです。 GD ライブラリには太字で表示できる関数はありません。解決策は少しばかばかしいもので、各キャラクターを 2 回描画することで、2 回目の描画の $x は最初の描画の $x よりも 1 ピクセル大きくなります。