ImageMagick 使用例 -- テキストの取り扱い
テキストのラベルを作成したり、画像にテキストを追加したりする処理は、ImageMagick が使われる用途のうちでも、おそらく最も基本的でよくあるもののひとつです。それは最も単純なもののひとつでもありますが、工夫次第で非常に凝った結果も得られます。そこで、IM の機能を探っていく出発点としては、ここがちょうどよいでしょう。
ImageMagick におけるテキスト演算子
ImageMagick には画像内にテキストを描画する方法がたくさんあり、この画像処理ライブラリの汎用性の高さがそこに表れています。このページでは、テキストを描画する具体的な手法とスタイルを詳しく説明します。これらの例を学ぶにあたって念頭に置いておくべきなのは、ImageMagick は本質的には画像のコンバータであり加工ツールだ、ということです。そのため、ここで紹介する各手法は、画像にラベルや著作権表示を追加するといった、単純なテキスト描画演算子にすぎません。画像への注釈付けを参照してください。すべてのテキスト演算子は、使用する "[-font](https://imagemagick.org/command-line-options/#font)"、"[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" といった標準的なテキスト処理設定一式を理解し、利用します。また "[-fill](https://imagemagick.org/command-line-options/#fill)" の色設定、さらに複雑なテキスト描画では "[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)"、"[-stroke](https://imagemagick.org/command-line-options/#stroke)"、"[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" の色も使います。ラベルやキャプションのように実際に新しい画像を作成する場合には、"[-background](https://imagemagick.org/command-line-options/#background)" の色設定も使われます。そして最後に、比較的新しい "[-kerning](https://imagemagick.org/command-line-options/#kerning)" や "[-interword-spacing](https://imagemagick.org/command-line-options/#interword-spacing)" といった修飾子もあります。ImageMagick が そうでない のは、本格的な整形済みテキスト・文書処理ソフトだという点です。重いテキスト処理を行いたいのなら、本格的な対話型ワードプロセッサや、"TeX"(あるいはその派生のいずれか。後述の 完全なテキスト処理システム を参照)のようなバッチ式のテキスト整形ツールを使ったほうがよいでしょう。これらのプログラムの出力(一般にはポストスクリプト形式)を、その後で画像に変換し、ImageMagick でさらに加工することができます。つまり、適材適所で正しいツールを使いましょう、ということです。とはいえ、ある程度のフォント混在処理は可能です。手始めとしては、このページの末尾近くにある 複数フォントスタイルの行を作成する を見てください。それでは、テキストを画像に「マジック」する基本的な方法を見ていきましょう。後ほど次のセクション(複合フォント)では、興味深いフォント効果の生成を見ていきます。
Label -- 単純なテキストラベル
基本的なラベル
"label:" 画像を使ってフォント画像を作成するのは、ImageMagick で手早くフォントを描画する、より一般的な方法です。最大の利点は、現在の "[-background](https://imagemagick.org/command-line-options/#background)" と "[-fill](https://imagemagick.org/command-line-options/#fill)" の色設定に従って、自前のキャンバスを生成し、それが描画されたテキストに合わせたサイズになる点です。たとえば、これが典型的に生成されるラベルです。
magick -background lightblue -fill blue \
-font Candice -pointsize 72 label:Anthony \
label.gif
上記は、フォントの選択と "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" で結果を決める、ラベルの最も典型的な使い方でしょう。しかし、テキストラベルを生成する方法としては、群を抜いて面白みのないものでもあります。 |
生成される 'label:' 画像は、同じ文字列を値とする 'label' 画像プロパティメタデータも持ちます。MIFF や PNG などの一部のファイル形式は、その特定のプロパティを保存でき、後続の画像処理プログラムで利用できます。'label' メタデータの利用例については、保存したメタデータを使った montage の例を参照してください。 |
|---|---|
"[-size](https://imagemagick.org/command-line-options/#size)" も指定すると、生成されるラベル画像はそのサイズで作成されます。 |
magick -background lightblue -fill blue -font Candice \
-size 165x70 -pointsize 24 label:Anthony label_size.gif
![[IM Output]](../static/img/text/label_size.gif)
"[-gravity](https://imagemagick.org/command-line-options/#gravity)" を使えば、その大きめのボックス内でのラベルの位置も設定できます。 |
magick -background lightblue -fill blue -font Candice \
-size 165x70 -pointsize 24 -gravity center \
label:Anthony label_gravity.gif
![[IM Output]](../static/img/text/label_gravity.gif)
もちろん、ラベルに "[-size](https://imagemagick.org/command-line-options/#size)" を設定しなければ、生成される "label:" には "[-gravity](https://imagemagick.org/command-line-options/#gravity)" が使える余白が一切できないため、グラビティはほとんど意味をなしません。"[-size](https://imagemagick.org/command-line-options/#size)" と "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" の両方を一緒に使う場合の問題は、テキストが指定した画像サイズから「あふれる」可能性があることです。 |
magick -background lightblue -fill blue -font Candice \
-size 165x70 -pointsize 72 -gravity center \
label:Anthony label_overflow.gif
![[IM Output]](../static/img/text/label_overflow.gif)
| バージョン 6.5.2-4 より前では、"[-size](https://imagemagick.org/command-line-options/#size)" 設定も指定されている場合、IM は "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" 設定を完全に無視していました。これにより、上記の画像中のテキストは「ベストフィット」処理(次の一連の例を参照)に従って自動的にサイズ調整されます。
---|---
画像へのベストフィット
特定の "[-size](https://imagemagick.org/command-line-options/#size)" の画像をラベルで生成するための最大のコツは、ラベルに "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を指定 しない ことです。こうすると、IM は要求された画像サイズに 最もよく合う フォントサイズを自由に選ぼうとします。つまり、描画されるテキストが、与えられたサイズに合わせて調整されるのです! |
magick -background lightblue -fill blue -font Candice \
-size 165x70 label:Anthony label_size_fit.gif
![[IM Output]](../static/img/text/label_size_fit.gif)
ご覧のとおり、"[-size](https://imagemagick.org/command-line-options/#size)" を設定すると、画像の右側や下側に余白ができることがあります。 | IM が「ベストフィット」ラベルを作成すると、実際に使われたポイントサイズも 'label:pointsize' 画像プロパティに保存され、その情報を後で利用できます。これは IM v6.6.2-7 で追加されました。フォーラムの議論 Pointsize Reporting の最中のことです。
---|---
"[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定を調整すれば、その余白内でのラベルの位置を依然として調整できます。 |
magick -background lightblue -fill blue -font Candice \
-size 165x70 -gravity center label:Anthony label_size_gravity.gif
![[IM Output]](../static/img/text/label_size_gravity.gif)
もちろん、ラベルに "[-size](https://imagemagick.org/command-line-options/#size)" を設定しなければ、生成される "label:" には "[-gravity](https://imagemagick.org/command-line-options/#gravity)" が使える余白が一切できないため、画像を特定のサイズにするよう要求したときにのみ意味があります。さて、最良の知らせです。与える "[-size](https://imagemagick.org/command-line-options/#size)" 設定がラベルの幅または高さのどちらか一方しか含んでいない場合、フォントはその与えられた寸法に最もよく合うように調整されます。指定されなかったもう一方の寸法は、そのテキストに合わせて自動調整されます! |
magick -background lightblue -fill blue -font Candice \
-size 160x label:Anthony label_size_width.gif
![[IM Output]](../static/img/text/label_size_width.gif)
要するに上記の "label:" は常に幅 160 ピクセルになり、その幅で最大のフォントサイズが使われます。ラベルの高さは、それに合わせて調整されます。幅ではなく高さが指定された場合も、同じことが行われます。 |
magick -background lightblue -fill blue -font Candice \
-size x40 label:Anthony label_size_height.gif
![[IM Output]](../static/img/text/label_size_height.gif)
このラベルは高さ 40 ピクセルで、未定義だったテキストのポイントサイズがその高さに合わせて調整され、その後、未定義だった幅が描画されたテキストに合わせて設定されました。まさに期待どおりです。もちろんこの場合も、"[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定が使える余白はほとんど、あるいは全くありません。
複数行にわたるラベル
"label:" ジェネレータは(IM バージョン 6.2.5 以降)複数行のラベルを生成できます。 |
magick -background lightblue -fill blue -font Ravie -pointsize 20 \
label:'ImageMagick\nRules - OK!' label_multiline.gif
![[IM Output]](../static/img/text/label_multiline.gif)
ご覧のとおり、"label:" は改行を表す '\n' の使用を理解します。これは、データをコマンドライン上に置く際、特殊文字がエスケープされるよう入力テキストを前処理しなければならない場合があることを意味します。詳しくは後述の テキスト引数における特殊エスケープ文字 を参照してください。"[-gravity](https://imagemagick.org/command-line-options/#gravity)" も "label:" の生成に影響する(IM バージョン 6.2.6 以降)ので、これを使って複数行ラベルを「両端揃え」できます。 |
magick -background lightblue -fill blue -font Corsiva -pointsize 24 \
-gravity center label:'ImageMagick\nExamples\nby Anthony' \
label_centered.gif
![[IM Output]](../static/img/text/label_centered.gif)
IM の重要な機能のひとつに、使用するテキストデータをファイルから読み込めることがあります。これは、ファイル名の前にアットマーク '@' を付け、それを文字列引数として使うことで行います。たとえば、ここでは私のワークステーションの 'message of the day' ファイルからラベルを作成します……。
magick -background lightblue -fill blue \
label:@/etc/motd label_file.gif
ラベル用のテキストを、標準入力のパイプラインから読み込むこともできます。たとえば、ここでは引用文ジェネレータの出力を複数行ラベルに「マジック」します。
mesgs ImageResolution |\
magick -background lightblue -fill blue \
label:@- label_file_multiline.gif
使用したファイル名がただの '-' 文字だったことに注目してください。これは、ファイルを標準入力から読み込むことを意味します。'@_filename_' を使えば、IM の どの コマンドライン文字列引数でもファイルから読み込めることを覚えておいてください。これには、以下で示す他のすべてのテキスト入力方法が含まれます。ただし、これは文字列引数の一部ではなく、文字列引数全体を置き換える用途にしか使えません。また、上記の例では、ラベル画像に余分な空行が追加されている点にも注意してください。この空行は、入力テキストファイルの末尾の改行が原因です。入力ファイルから末尾の改行を何らかの方法で取り除かない限り(修正方法については後述の caption: の例を参照)、"label:" は入力テキストファイルからこの空行を常に持つことになります。 |
ほとんどの古いバージョンの IM(v6.2.5 より前)は、複数行のラベルを扱えません。これらのバージョンでは、各行がつなぎ合わされて、非常に非常に長い 1 行になっていたでしょう。 |
|---|---|
縦書きラベル
もちろん、入力テキスト自体に改行を追加することもできます。たとえば、ここでは単純な単語を取り、1 文字ごとに改行を挟んで、中央揃えの縦書きテキストを作成します。 |
echo -n "Vertical" | sed 's/./&@/g; s/@$//' | tr '@' '\012' |\
magick -background lightblue -fill blue -font Ravie -pointsize 24 \
-gravity center label:@- label_vertical.gif
"sed" コマンドは、文字列の末尾を除く各文字の後に '@' 文字を追加していることに注意してください。次に "tr" が '@' 文字を改行に置き換えます。これは入力テキストが改行で終わっていないことも前提としています。改行で終わっていると、結果画像の下部に余分な空白が追加されてしまいます。 ![[IM Output]](../static/img/text/label_vertical.gif)
linux を使っていて、したがって GNU 版の "sed" コマンドを使っているユーザーは、"tr" を取り除き、sed コマンド内の '@' を '\n' に置き換えることで、各文字の間に改行を直接挿入できます。各文字の間隔を調整するために使える特殊な属性 行間スペース も参照してください。
Caption -- ワードラップされるラベル
テキスト入力からの "caption:" 画像ジェネレータは、ほとんどの点で "[label:](#label)" とまったく同じですが、指定された "[-size](https://imagemagick.org/command-line-options/#size)" 設定に合わせてテキストのサイズを拡大する代わりに、指定された "[-size](https://imagemagick.org/command-line-options/#size)" の幅に収まらない長い行をワードラップする点が異なります。ただし "[-size](https://imagemagick.org/command-line-options/#size)" 設定は省略可能ではなく、少なくとも最大幅をピクセルで指定しなければなりません。たとえば、これは指定した幅に収まらない長い行のキャプションです。
magick -background lightblue -fill blue -font Corsiva -pointsize 36 \
-size 320x caption:'This is a very long caption line.' \
caption.gif
| 生成される 'caption:' 画像は、同じ文字列が「設定」された "caption" 画像プロパティメタデータも持つため、その情報を後で再利用できます。一般的な画像ファイル形式はすべて、この情報を画像とともに保存します。例については 保存したメタデータを使った montage を参照してください。
---|---
デフォルトではテキストはすべて左揃えですが、IM バージョン 6.2.0 以降、"caption:" はテキストの揃え方の用途で "[-gravity](https://imagemagick.org/command-line-options/#gravity)" を尊重します。
magick -background lightblue -fill blue -font Candice -pointsize 40 \
-size 320x -gravity Center caption:'ImageMagick Rules OK!' \
caption_centered.gif
"[-size](https://imagemagick.org/command-line-options/#size)" 設定に幅だけでなく高さも与えると、画像の高さもその高さに設定されます。その場合、"[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定を使って、テキストを垂直方向に配置することもできます。
magick -background lightblue -fill blue -font Gecko -pointsize 32 \
-size 320x100 -gravity South caption:'Captions at their height!' \
caption_height.gif
ただし、与えられた "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" で指定した "[-size](https://imagemagick.org/command-line-options/#size)" に(高さ方向に)テキストが収まらない場合、テキストはボックスからあふれることに注意してください。テキストのどの部分が切り落とされるかは、当然ながら現在の "[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定で決まります。たとえばこれは前の例とまったく同じですが、結果に対して小さすぎる画像 "[-size](https://imagemagick.org/command-line-options/#size)" を使っています。
magick -background lightblue -fill blue -font Gecko -pointsize 32 \
-size 320x60 -gravity South caption:'Captions at their height!' \
caption_height_toosmall.gif
ベストフィットのキャプション
IM v6.3.2 以降、最終画像の幅と高さの両方を与え、フォントの "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を定義しない(または "[+pointsize](https://imagemagick.org/command-line-options/#pointsize)" でポイントサイズを無効にする)と、IM は要求された画像の "[-size](https://imagemagick.org/command-line-options/#size)" を最もよく埋めるように、フォントのサイズを自動調整しようとします。たとえば、ここでは ImageMagick にかなり大きな領域を埋めるよう指示します……。
magick -background lightblue -fill blue -font Candice -size 320x140 \
caption:'This text is resized to best fill the space given.' \
caption_filled.gif
そして今度は、同じフォントとテキスト文字列に対して、はるかに小さく細い領域です。 |
magick -background lightblue -fill blue -font Candice -size 80x110 \
caption:'This text is resized to best fill the space given.' \
caption_filled_sm.gif
![[IM Output]](../static/img/text/caption_filled_sm.gif)
直前の 2 つの例で唯一異なるのは、生成される画像の "[-size](https://imagemagick.org/command-line-options/#size)" だけだという点に注意してください。IM は指定された画像サイズを最もよく埋めるように、テキストとワードラップを合わせました。これは、未知のテキスト片を、領域の境界からあふれさせることなく、与えられた空間に収めるのに非常に便利です。ただし内部的には、IM が与えられた空間を最もよく埋めるための正しいポイントサイズを探すため、caption を複数回実行するのと同等です。言い換えると、使用する特定の "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を与えた場合に比べて、10 倍以上遅くなることがよくあります。
段落を含むキャプション
"caption:" 画像演算子は(IM v6.2.5 以降)、改行または段落を意味するものとして '\n' のシェルエスケープの使用を理解します(したがってバックスラッシュをエスケープするには二重のバックスラッシュ '\\' にする必要があります)。このバージョンより前は、別々の段落は別々の "caption:" 操作で処理しなければなりませんでした。
magick -background lightblue -fill blue \
-font Ravie -pointsize 24 -size 360x \
caption:"Here I use caption to wordwrap.\nTwo separate lines." \
caption_multi_line.gif
"[label:](#label)" と同様に、'@' ファイル名プレフィックスを使って、描画するテキストをファイルや(前のパイプラインコマンドからの)標準入力から読み込むことができます。
mesgs FilePrivate |\
magick -background lightblue -fill blue -pointsize 12 \
-size 320x caption:@- caption_file.gif
ご覧のとおり、入力テキスト中の改行は(IM v6.2.5 以降)段落の区切りとして扱われます。これには入力ファイル末尾の改行も含まれます。もちろん "[label:](#label)" は行をワードラップせず、そのまま保持します。本当にファイルを単一の段落として扱いたい場合は、改行文字をスペース文字に置き換えて、テキストをすべて 1 行にする必要があります。たとえば、ここでは同じテキストを取り、改行をスペースに置き換えてから、単語間の複数のスペースを単一のスペースに置き換えます……。
mesgs FilePrivate | tr '\012' ' ' | sed 's/ */ /g' |\
magick -background lightblue -fill blue -pointsize 12 \
-size 320x caption:@- caption_one_line.gif
ご覧のとおり、このほうがずっとうまくいきます。しかし、よく望まれるのは、空行を段落の区切りとして扱うことです。それには、空行に関わるもの以外のすべての改行を取り除く必要があります。ここに、そのようなテキストを "caption:" が必要とする形式に「マジック」する特別な "sed" コマンドを示します。この場合のテキストは "magick" の man ページの最初のページです。
man magick | col -b | expand | \
sed '/^$/d; :loop y/\n/ /; N; /\n$/! b loop; s/ */ /g; s/^ //' |\
head -n 7 | magick -size 400x caption:@- caption_manual.gif
| caption には「両端揃え」のテキストオプションはありません。しかし pango: テキスト整形ツール(外部ライブラリを使用)には、その機能があり、さらに多くの機能があります。
---|---
テキスト属性
もともと、テキスト処理に影響する設定には次のものがありました。"[-font](https://imagemagick.org/command-line-options/#font)"、"[-fill](https://imagemagick.org/command-line-options/#fill)"、"[-pointsize](https://imagemagick.org/command-line-options/#pointsize)"、"[-size](https://imagemagick.org/command-line-options/#size)"、"[-gravity](https://imagemagick.org/command-line-options/#gravity)"。これらの属性制御の多くは、すでに上で紹介しました。しかし、あまり頻繁には使われず、もともとは "label:" や "caption:" のテキスト画像生成に影響しなかった他の属性制御もあります。IM v6.3.2 以降は、"label:" や "caption:" でも "[-stroke](https://imagemagick.org/command-line-options/#stroke)"、"[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)"、"[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" を使えます。たとえば、ここでは IM のテキスト画像レンダリングの属性を制御するために、多くの異なる設定を使ってみます……。 |
magick -background white -fill dodgerblue -font Candice \
-strokewidth 2 -stroke blue -undercolor lightblue \
-size 165x70 -gravity center label:Anthony label_color.gif
![[IM Output]](../static/img/text/label_color.gif)
これらの設定の詳細については、後述の アンダーカラーボックス、および描画セクションの Stroke, StrokeWidth を参照してください。 | 現時点では、"[-tile](https://imagemagick.org/command-line-options/#tile)"、"[-fill](https://imagemagick.org/command-line-options/#fill)"、"[-background](https://imagemagick.org/command-line-options/#background)"、"[-origin](https://imagemagick.org/command-line-options/#origin)" で定義したタイリング画像を、"label:" や "caption:" のいずれとも併用することはできません。使えるのは単色のみです。使おうとすると、未定義の(黒)色になるだけです。
---|---
ポイントサイズ、解像度、そして実際のフォントサイズ
ピクセルとは、ディスプレイ上や画像内のドットのことで、IM が扱う単位はこれです。一方、画像は特定の解像度(「1 インチあたりのドット数」(dpi)または「1 インチあたりのピクセル数」(ppi)で指定)で印刷されます。そのため、画像の解像度は、他のプログラムが画像を特定の媒体上でどのようにサイズ調整するかに影響します。例:実世界での画像の物理サイズに影響します。画像の解像度(density または dpi)は、画像のピクセルサイズや、画像がメモリやディスク上で占める容量とは無関係です。また、一般的に、ほとんどの IM の画像操作とも無関係です。そのため ImageMagick にとって、解像度は単に画像とともに保存される数値の組にすぎず、通常は無視されます。画像の解像度や density が関係してくる唯一の場面は、フォントと、ポストスクリプト・pdf・MWF のようなベクター形式を IM が扱うラスター画像形式に変換するときです。"[-density](https://imagemagick.org/command-line-options/#density)" 設定は、出力デバイス上に 1 インチあたり何ピクセル(ドット)(ppi)あるかを IM に伝え、IM はそれを使って画像生成とフォントサイズを合わせるよう調整できます。たとえば、デフォルトでは IM は 72 ppi の "[-density](https://imagemagick.org/command-line-options/#density)" 設定で動作します。これはモニタや Web ページ上で画像を表示する際の典型的な設定です。フォントのサイズは「ポイント」で指定され("[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を使用)、定義上 1 ポイントは 1/72 インチなので、72 ポイントのフォントは、おおよそ高さ 1 インチのサイズのテキストを生成するはずです……。 |
magick -pointsize 72 label:Hello pointsize.gif
![[IM Output]](../static/img/text/pointsize.gif)
しかし、ほとんどの最新ディスプレイはこれより高い解像度を持ち、典型的には 1 インチあたり 90 から 120 ピクセル(ppi)のどこかです。そのため……。 |
magick -density 90 -pointsize 72 label:Hello density.gif
![[IM Output]](../static/img/text/density.gif)
は、90 dpi のディスプレイ上で高さ 1 インチのラベルを生成するはずです。私のディスプレイではそうなります!これらの画像の高さを画面上で測れば、ご自分のディスプレイの解像度を確認できます。1 インチあたりのピクセル数が大きくなると、描画されるフォントも当然ながら画像内のピクセル数の点で大きくなり、したがって大きな画像が生成されます。異なる画像プログラムはしばしば異なるデフォルト density を持つため、同じポイントサイズでも、異なるプログラムで描画されたフォントが違って見えることがあります。"[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" は実際にはフォントの 行間隔(正確にはその描画領域の高さ)を意味し、描画される文字の実際の高さを指すのではないことに注意してください。そのため、同じポイントサイズと density でも、あるフォントは別のフォントより大きく見えたり小さく見えたりします。実際に同じになるのはフォントの行間隔だけで、それ以外はフォントとフォントのデザイナー次第です。そのため、デフォルトの 72 dpi(このとき 1 ポイント = 1 ピクセル)の "[-density](https://imagemagick.org/command-line-options/#density)" では、12 ポイントのフォントは 2 行のテキストのベースライン間に 12 ピクセルの間隔を持つはずです。 | 生成される "[label:](#label)" 画像の高さは、画像の描画領域またはバウンディングボックスに基づき、それはしばしばフォントの行間隔とポイントサイズです。常にそうとは限らないので、単にテキストの行を縦に連結するのは、実際には正しくないフォントの扱いです!
---|---
一部のフォントは、通常の行間隔の境界をはるかに超えて、行間隔の上、あるいはより一般的には下にはみ出して描画されることさえあります。これは手書き風のスクリプトフォントで特に顕著です。フォントの 見た目 は、フォントの "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" と "[-density](https://imagemagick.org/command-line-options/#density)" にも影響されます。フォントのポイントサイズを倍にする("-pointsize 24")と、density や解像度を倍にしたものとほぼ同じ大きさに見えるフォントが生成されます。しかし、フォントは特定の見た目になるよう設計されているため、フォント内の線の太さは、より大きなポイントサイズでもあまり変わらないことがあります。つまり、より大きなフォントサイズは、わずかに異なります。しかし density だけを倍にする("-density 144")と、12 ポイントのフォントは寸法が倍になって描画され、それでも元の 12 ポイントフォントのように見えるはずですが、ただより大きなスケールで、エッジのスムージングがよりよくなって描画されます。ただし、非常に低い解像度では、ピクセルの物理的なサイズの制約もフォントの見た目に影響することがあります。これは、density が定義する大きなピクセルサイズのために、低い density では細い線が太くなる可能性があることを意味します。'density' と 'pointsize' の関係は非常に複雑な問題であり、プロのフォントグラフィックデザイナーだけが完全に理解し、それを正しく扱えるようにフォントを設計できるものです。IM フォーラムの Lithium によると……。
これは TrueType フォントレンダラーの機能だと思います。TrueType のグリフは単なる曲線の集合ではなく、複数の詳細レベルと、出力のピクセルサイズに応じて点の座標を調整する命令を含むことがあり、それはピクセルサイズが小さいときによりはっきりと現れます。そのため、小さなテキストは、縮小された大きなテキストとは違って見えます(より鮮明だと気づくでしょう)。
FUTURE Example: difference between font at same 'pixel' size, but different density and point size. 基本的に、これらの要因の一方を増やし、もう一方を同じだけ減らしても、同じ結果に ならない ことがあります。特に線の太さやフォント全体の「スタイル」に関してそうです。やろうとしていることに適した要因を調整したほうがよいでしょう。出力デバイス向けにフォントをスケールするときや、後でフォントをリサイズするときには "[-density](https://imagemagick.org/command-line-options/#density)" を、通常のフォントサイズの変更には "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を使ってください。フォントについてもっと知りたければ、私が非常に興味深いと感じたドキュメント TrueType Fundamentals (PDF) を見てください。
ラベル画像の境界
一部の風変わりなフォントを使うと、フォントが拡張文字を使うことがあり、かつて IM はこれらのフォントのラベル作成に多くの問題を抱えていました。つまり、テキストが用意されたキャンバスからあふれてしまうのです。たとえば、ここに、有名なある清涼飲料を彷彿とさせる 'LokiCola' フォントの大文字 2 文字を示します。 |
magick -background lightblue -fill blue -font LokiCola -pointsize 64 \
label:HC label_overflow_font.gif
![[IM Output]](../static/img/text/label_overflow_font.gif)
ご覧のとおり、IM はこのフォントの先頭や末尾の装飾を切り落とすことなく、ラベル内に収めることに成功しています。 | IM v6.3.2 より前では、上記の例で "[label:](#label)" は 'H' のリードインと、両方の文字の尾の部分を切り落としていたでしょう。
---|---
この問題が存在した理由は、フォントの「グリフ」つまり文字の記述が、特定の文字についてフォントが定義した境界の外側に描画され、(一般には上または下に)フォント内の他の文字と重なることを許しているからです。これはフォント自体の設計・定義の仕方の問題であり、IM の落ち度ではありませんでしたが、IM は今ではこうした奇妙な状況をユーザーの利益を最優先して扱います。他の状況では依然として問題になりうるもので、複数行テキストの相互作用のために単純には解決できないものです。より詳しい説明については、後述の バウンディングボックスのあふれ の例を参照してください。
Unicode または UTF8 形式のテキスト
IM に文字列引数を与えるこの方法は非常に重要です。なぜなら、通常ならコマンドラインから行うのが非常に難しいことを可能にするからです。具体的には「unicode テキスト」の扱いや、文字コードを使った特定の文字の選択です。さて、unicode 文字をコマンドやスクリプトに入力できるなら、それらを直接使えます……。
magick -background lightblue -fill blue -pointsize 32 \
label:' é è à ù ç Ö ÿ ‘ ’ “ ” ° ² ³ € x ÷ ' label_i8n.gif
しかし、unicode 文字の入力を適切に扱えるようキーボードやエディタを設定している人はほとんどいません。unicode 文字を直接入力できなくても、ひとつの簡単な解決策は、既存の UTF-8 テキストファイルや Web ページから、目的の文字を「コピー&ペースト」するだけです。私はそうしています!描画したい UTF-8 テキストがすでに生成済みなら、'@filename' を使ってファイルから直接読み込めます。たとえば、ここでは UTF-8 エンコードの中国語テキストファイル(ファイル末尾に改行なし)から中国語のラベルを作成します。
magick -background lightblue -fill blue -pointsize 48 \
-font ZenKaiUni label:@chinese_words.utf8 label_utf8.gif
| _上記の例で使われているフォントは特別なもので、中国語のグリフ一式が定義されています。たとえば fedora linux のフォント 'SimSun'(あるいはフォントファイル "gkai00mp.ttf" 内)、"ZenKaiUni"(ファイル "ukai.ttf" 内)、"ShanHeiSunUni"(ファイル "uming.ttf" または "zysong.ttf" または "bsmi00lp.ttf" のいずれか内)です。
なお、windows のフォント 'Mincho'(後の例で使用)も多くの中国語グリフを定義していますが、不完全です。上記でこれを使うと、未定義のグリフについていくつか疑問符が表示されます。
特別なスクリプト "[imagick_type_gen](../static/img/scripts/imagick_type_gen)" を使って、フォントの正式名を見つけて抽出し、そのフォントを ImageMagick の "type.xml" 設定ファイルに追加しました。
_
---|---
(linux システム上で)'GNU' の "printf" プログラムを使って unicode 番号を特定の UTF-8 エンコード文字列に「マジック」することで、unicode 文字コードから UTF-8 文字列を生成することもできます。この場合は、適切に組版された開きと閉じの引用符です(やはり UTF-8 入力の末尾に改行なし)。たとえば、ここでは unicode 文字コードを使って UTF-8 テキストを生成し、実際のファイルからではなく、コマンドパイプライン経由で("@-" を使って 'stdin' から読み込んで)渡します。
env LC_CTYPE=en_AU.utf8 \
printf "‘single’ - “double”" | \
magick -background lightblue -fill blue -pointsize 36 \
label:@- label_quotes.gif
他のシステム(Mac OSX や Windows など)では、perl の "printf" を使って、unicode 文字コードから UTF-8 エンコードの文字列を出力できます。
perl -e 'binmode(STDOUT, ":utf8"); \
print "\x{201C}Unicode \x{2018}\x{263A}\x{2019} Please\x{201D}";' |\
magick -background lightblue -fill blue -pointsize 36 \
label:@- label_unifun.gif
詳しい情報や、さまざまな言語・記号の unicode 文字コードを調べるには、Unicode Character Code Charts を参照してください。unicode 文字には国際的な文字を含められるだけでなく、適切なフォントを使えば、それが定義する特別な「記号」セットも使えます。その最も有名なものが 'DingBats' 記号フォントです。このフォントは今やとても一般的になったので、現在では標準の Unicode フォントセットの一部になっています。たとえば、ここでは私が書いた特別な "**[graphics_utf](../static/img/scripts/graphics_utf)**" シェルスクリプトを使って、'DingBats' unicode 記号領域の最初の 24 文字を、unicode 文字の「ブロック」を UTF-8 テキストとして生成して抽出します。
graphics_utf -N 2701 2718 |\
magick -font Mincho -pointsize 32 label:@- label_dingbats.gif
上記の疑問符は、unicode または windows の 'Mincho' フォントのいずれによっても定義されていなかった特定の文字です。より具体的には、元の 'dingbat' フォントの一部だった記号は unicode 内に存在しますが、期待される dingbat コードとは別の unicode 文字コードを使っています。詳しくは Dingbats Unicode Specification Chart と、その中の「欠けている」dingbat 文字に使うべき正しい unicode 文字への参照を見てください。疑問符の代わりに、多くのフォントはそうした未定義文字に対して、ただボックスや空白文字を表示します。出力にそうした文字や欠けた文字が多すぎる場合は、おそらく別のフォントを使うべきです。巨大な unicode 文字フォントの一部として利用できる他の記号セットには、トールキンのルーン文字、数学記号、ローマ数字、矢印、点字、技術記号などがあります。それは探検しがいのある大きなセットで、"**[graphics_utf](../static/img/scripts/graphics_utf)**" シェルスクリプトが探検の助けになります。ここに、Microsoft の 'Mincho' フォントがレンダリングできる unicode 文字のもうひとつの例を示します。この場合は「その他の記号」セクションのものです……。
graphics_utf -N 2620 2630 |\
magick -font Mincho -pointsize 40 label:@- label_misc.gif
DOS スクリプト内で unicode を使うのは、UNIX や LINUX 上よりずっと難しいです。その環境から unicode を使う際の特別な注意事項は、Wolfgang Hugemann によって Windows Character Encoding に記載されています。
記号フォント
特別なテキスト画像を探している人によりよく使われるのが、特別な「記号フォント」です。これらは巨大な完全版 Unicode フォントよりずっと小さく、通常の標準 ASCII 文字(文字や数字)を、特定の形状や画像の別のセットで置き換えるだけです。とはいえ、まれにラテン文字のメタ文字領域により多くの記号を持つこともあります。'DingBat' フォントの記号はこのように始まりましたが、上で述べたとおり、今では Unicode 文字セットの一部です。たとえば、私がよく使うのが好きな記号のひとつは、フォント "WebDings" のものです。これは、そのフォントの定義で通常の 'Y' 文字を置き換える、なかなか素敵な「曲線的なハート」記号です……。
magick -size 20x20 -gravity center -font WebDings label:Y label_heart_20.gif
magick -size 40x40 -gravity center -font WebDings label:Y label_heart_40.gif
magick -size 60x60 -gravity center -font WebDings label:Y label_heart_60.gif
magick -size 80x80 -gravity center -font WebDings label:Y label_heart_80.gif
覚えておくべき重要なことは、すべての truetype フォントは、実際には特別な種類の ベクター画像形式 だということです。フォント内には複数の画像(文字ごとに 1 つ)があります。それらはベクター画像なので、"[-size](https://imagemagick.org/command-line-options/#size)"、"[-pointsize](https://imagemagick.org/command-line-options/#pointsize)"、"[-density](https://imagemagick.org/command-line-options/#density)" が提供する制御を使って、フォントで文字・形状・記号を、ほぼ任意のサイズ(スケール)で「描画」できることを意味します。上でご覧のとおり、「曲線的なハート」は私が望むほぼ任意のサイズで「レンダリング」できます。一部のフォントは非常に特殊です。たとえば IDAutomation から、バーコードの生成に使える "IDAutomationHC39M.ttf" というフォントファイルを入手できます。たとえば……。
![[IM Output]](../static/img/text/label_heart_80.gif)
|
magick -font IDAutomationHC39M -pointsize 16 label:'*314-76*' \
-bordercolor white -border 5x5 label_barcode.gif
![[IM Output]](../static/img/text/label_barcode.gif)
ここに、何らかの理由で集めてきたさまざまな記号フォントの中から見つけた、他の興味深い記号をいくつか示します……。
magick -pointsize 48 -font WebDings label:' " _ ~ ) - ' label_webdings.gif
magick -pointsize 48 -font LittleGidding label:' x o w ' label_ltgidding.gif
magick -pointsize 48 -font WingDings2 label:'ab' label_wingdings2.gif
magick -pointsize 48 -font Zymbols label:' ? , - I Z ' label_zymbols.gif
magick -pointsize 48 -font TattoEF label:' B Y D I H ' label_tatooef.gif
magick -pointsize 48 -font SoundFX label:' V 3 t f 9 ' label_soundfx.gif
これは利用可能なもののほんの一部にすぎません。考えうるありとあらゆる記号・形状・画像の巨大なライブラリが、閲覧してダウンロードできるよう WWW 上に用意されています。
![[IM Output]](../static/img/text/label_soundfx.gif)
| 描画される各文字には、別々に描画できる 2 つの部分があることを覚えておいてください。「塗りつぶし」領域(上で示したもの)と、「ストローク」つまり輪郭で、これは塗りつぶし領域とはまったく違って見えることがあります。これらの領域はそれぞれ別々に、あるいは異なる色で描画できるので、有望な記号や形状をいくつかの方法でより詳しく調べてみるのはよい考えかもしれません。とても意外な結果が得られるかもしれません。これを行う例については 複合フォント、ストローク を参照してください。
| _記号フォントの作者の多くは、適切な設計や画像・形状のクリーニングをせずに、単純なスキャナとビットマップ→ベクターコンバータを使って形状を生成しています。そうした「スキャンされた」フォントを見るときには注意をお勧めします。
上で示した最後のフォントは、そうした「スキャンされた」フォントの一例で、他のよりきちんと設計されたフォントと比べると、見た目が粗い「ドットだらけ」の質感になっています。_
---|---
文字間カーニング
IM v6.4.7-8 以降、"[-kerning](https://imagemagick.org/command-line-options/#kerning)" を使って、テキスト文字列内の各文字の間に余分な文字間スペースを挿入できます。たとえば |
magick -pointsize 12 label:Anthony label_kerning_0.gif
magick -pointsize 12 -kerning 1 label:Anthony label_kerning_1.gif
magick -pointsize 12 -kerning 2.5 label:Anthony label_kerning_2.gif
magick -pointsize 12 -kerning 5 label:Anthony label_kerning_5.gif
magick -pointsize 12 -kerning -1 label:Anthony label_kerning-1.gif
![[IM Output]](../static/img/text/label_kerning-1.gif)
実際のカーニング値は、浮動小数点値でも、あるいは負の値でもよいことに注意してください。負の "[-kerning](https://imagemagick.org/command-line-options/#kerning)" 値を使う別の例については、連結複合フォント の例を参照してください。
単語間スペース
これも IM v6.4.8-0 以降、オプション "[-interword-spacing](https://imagemagick.org/command-line-options/#interword-spacing)" を使って、単語間に使われるスペース文字のサイズを変更できます。たとえば |
magick label:'I Love IM!' label_wspace_off.gif
magick -interword-spacing 1 label:'I Love IM!' label_wspace_1.gif
magick -interword-spacing 10 label:'I Love IM!' label_wspace_10.gif
magick -interword-spacing 25 label:'I Love IM!' label_wspace_25.gif
![[IM Output]](../static/img/text/label_wspace_25.gif)
単語間のスペース文字のサイズを大きくできるだけでなく、デフォルトのサイズより小さくもできることに注目してください。ただし、スペースは単語をピクセル境界に再整列させる(上記の 文字間カーニング とは異なり)ので、スペースをゼロに設定したラベルの出力は、スペースをまったく含まないラベルとはやはり異なります。文字間カーニング と 単語間スペース の両方は、IM がテキスト文字列を特定サイズの画像に自動的にフィットさせる能力の結果にも影響します。 |
magick -size 150x label:'I Love IM!' label_wsize_of.gif
magick -size 150x -interword-spacing 25 label:'I Love IM!' label_wsize_25.gif
magick -size 150x -interword-spacing 50 label:'I Love IM!' label_wsize_50.gif
![[IM Output]](../static/img/text/label_wsize_50.gif)
何が起きているかというと、"[-interword-spacing](https://imagemagick.org/command-line-options/#interword-spacing)" を設定することで、'スペース' 文字のサイズが残りのテキストサイズに合わせて変わらなくなるのです。そのため、IM が最適な "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" を割り出そうとするとき、各単語間のスペースの量は固定され、テキストを与えられた固定幅にフィットさせる際に何の役割も果たしません。結果として、"[-interword-spacing](https://imagemagick.org/command-line-options/#interword-spacing)" が大きいほど、同じ指定画像幅にテキスト行を実際に収めるのに必要なフォントサイズは小さくなります。負の値も使え、実際、特定の文字やフォントを使って単語を重ねたり、変わった効果を生み出したりできます。しかし負にしすぎると、未定義の挙動が入り込むことがあります。これを試すなら注意が必要です。上記はテキストの両端揃えの例ではありません(そう見えますが)が、これらのオプションを、適切なテキストの両端揃えを提供する出発点として使えます。本当にそのレベルのテキスト整形と両端揃えが必要なら、整形済みテキストや ポストスクリプト を生成する他の方法、たとえばコマンドラインベースの "TeX" や "LaTeX" ソフトウェアを検討したほうがよいかもしれません。さらによいのは、SVG(rsvg ライブラリ版)や Pango Markup Language(後述)を使って、両端揃えのテキストを生成することです。
行間スペース
IM v6.5.5-8 以降、もうひとつのオプション "[-interline-spacing](https://imagemagick.org/command-line-options/#interword-spacing)" が追加されました。これは以上の設定を踏まえてユーザーから強く要望されたもので、多くの点ではるかに便利です。基本的には、これは個々のテキスト行の間にこの数だけピクセルを加えたり引いたりします。つまり、これを使って個々のテキスト行を広げたり詰めたりできます。たとえば……。
magick label:'First\nSecond' label_lspace_off.gif
magick -interline-spacing 5 label:'First\nSecond' label_lspace_5.gif
magick -interline-spacing 10 label:'First\nSecond' label_lspace_10.gif
magick -interline-spacing 20 label:'First\nSecond' label_lspace_20.gif
magick -interline-spacing -5 label:'First\nSecond' label_lspace-5.gif
magick -interline-spacing -10 label:'First\nSecond' label_lspace-10.gif
この設定を最大限に活用するには、特定のフォントの通常の行間隔を計算できる必要があります。これはまさに "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" の定義であり、現在の解像度つまり "[-density](https://imagemagick.org/command-line-options/#density)" 設定とともにフォントの行間隔を定義します。これは実際にはフォントの実際の高さや線の太さを定義するものではありませんが、フォントのこれらの側面に影響します。そこで、"[-density](https://imagemagick.org/command-line-options/#density)" を '72' ドット毎インチとし、定義上 1 インチあたり 72 個の「ポイント」があると知っていれば、12 ポイントのフォントは 12 ピクセルの行間隔を持つと計算できます。その情報があれば、"-interline-spacing 12" の設定を使って、12 ポイントのテキスト行を「ダブルスペース」にできます。これは行間に余分な 12 ピクセルを加えます。 |
magick -density 72 -pointsize 12 -interline-spacing 12 -font Arial \
label:'First\nSecond\nThird' label_lspace_double.gif
![[IM Output]](../static/img/text/label_lspace_double.gif)
もちろん、単語間スペースで先に見たとおり、テキスト要素間に一定数のピクセルを加えると、自動ポイントサイズ処理が使われるときにはテキストが小さくなりがちです。つまり、最終的な画像の "[-size](https://imagemagick.org/command-line-options/#size)" が "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" 設定なしで与えられた場合です。 |
magick -size x70 -interline-spacing 18 -font Arial \
label:'First\nSecond\nThird' label_lspace_size.gif
![[IM Output]](../static/img/text/label_lspace_size.gif)
負の行間スペースは、行を繰り返してベースライン間隔より 1 ピクセル多く引くだけで、行を縦方向に「太字化」する間に合わせの手軽な方法としても使えます。 |
magick -density 72 -pointsize 12 -interline-spacing -13 -font Arial \
label:'Bolded Word\nBolded' label_lspace_vbold.gif
![[IM Output]](../static/img/text/label_lspace_vbold.gif)
もちろん、本当に 2 行が必要で、テキストの太字化ではない場合、これはうまくいきません。また、固定幅フォントでよりうまく機能します。
テキスト引数における特殊エスケープ文字
さまざまなテキスト引数で使われる特殊エスケープ文字は、すでに上で紹介しました。具体的には、バックスラッシュ '\' を使って改行のような特殊文字をエスケープしたり、画像プロパティ のページで定義されているパーセント '%' エスケープを使って文字列に追加情報を挿入したりできます。また、行の先頭で使われると、残りのテキスト引数を、指定されたファイル(または '-' が使われている場合は STDIN)からデータを読み込むファイル名として使う、特別な '@' エスケープがあります。 |
一部のシステム(ubuntu など)は、セキュリティポリシーを使って '@{file}' エスケープの使用を無効にしています。お使いのシステムにどのようなポリシーが、どこから設定されて存在するかを見るには magick -list policy と入力してください。 |
|---|---|
これらのエスケープ文字は、"magick identify"(および "[-identify](https://imagemagick.org/command-line-options/#identify)" と "[info:](files.html#info)")が使う "[-format](https://imagemagick.org/command-line-options/#format)" に影響するだけでなく、"[label:](#label)" や "[caption:](#caption)" のテキスト→画像ジェネレータにも影響し、画像メタデータ設定オプション "[-label](https://imagemagick.org/command-line-options/#label)"、"[-comment](https://imagemagick.org/command-line-options/#comment)"、"[-caption](https://imagemagick.org/command-line-options/#caption)" も制御します。そして最後に、これらは "[-annotate](https://imagemagick.org/command-line-options/#annotate)" でも使われます。 |
_バックスラッシュ '\' は "[-draw](https://imagemagick.org/command-line-options/#draw)" の 'text' メソッドで使われますが、パーセント '%' エスケープは 使われません。ImageMagick の SVG 画像処理と干渉するためです。これは IM バージョン 6 で "[-annotate](https://imagemagick.org/command-line-options/#annotate)" 演算子が作られた理由のひとつでした。 |
---|---
エスケープ文字についてもうひとつ重要な点は、これらはコマンドラインのテキスト引数には使われる一方で、テキストファイルから読み込まれるデータ(通常は '@' エスケープを使って読み込む)の中では一切適用されないことです。これは、テキストファイルのデータについて「エスケープ」をエスケープする心配をしなくてよいことを意味しますが、同時に、テキストに情報を挿入する必要がある場合は、IM の外で自分でファイルデータを処理しなければならないことも意味します。 | _入力テキストファイルをエスケープ処理から保護することは、IM バージョン 6.3.3 で最終決定されました。
---|---
たとえば、ここでは、ソーステキストファイルから情報を設定する 2 つの方法を使って、画像の 'label' と 'comment' メタデータを設定し、報告します。"info.txt" ファイルには文字列が含まれています
、(末尾の改行なし)。 |
magick -label @info.txt rose: -format '%l label' info:
magick -comment @info.txt rose: -format '%c set "' info:
magick rose: -set label @info.txt -format '%l caption' info:
magick rose: -set comment @info.txt -format '%c set "' info:
| ![[IM Text]](../static/img/text/file.txt.gif)
IM が '@' ファイル読み込みエスケープを使って読み込んだエスケープ文字シーケンスを、一切展開 しなかった ことに注目してください。これは重要です。なぜなら、IM がファイルからテキストを読み込むときはいつでも、そのファイル内にあった特殊文字を 決して 扱わないことを意味するからです。
IM はテキストファイルを、エスケープなしの、文字どおりのテキストとして読み込む
残念ながら、これにはファイル(やストリーム)内に存在するかもしれない末尾の改行も含まれます!これは、入力テキストの末尾に改行がある場合(これは非常によくある慣行です)、結果画像に余分な「空」行が生じる原因となります。たとえば……。 |
echo "Anthony" | magick label:@- label_stdin.gif
![[IM Output]](../static/img/text/label_stdin.gif)
ご覧のとおり、ラベルには入力文字列が含まれただけでなく、"echo" コマンドが末尾に追加した改行文字のために、余分な空行も含まれています。その末尾の改行が不要なら、自分で取り除く必要があります。ただしこれは、テキストがどこでどのように取得・作成されるか、また IM をどの API から実行しているかによっては、厄介な問題になりえます。最良の方法は、そもそもその末尾の改行を生成しないようにすることです。たとえば "echo" に '-n' フラグを使うことです。 |
echo -n "Anthony" | magick label:@- label_stdin_2.gif
![[IM Output]](../static/img/text/label_stdin_2.gif)
あるいは、特に要求しない限り余分な改行を追加しないものを使うことです。 |
printf "Anthony" | magick label:@- label_stdin_3.gif
![[IM Output]](../static/img/text/label_stdin_3.gif)
あるいは、ちょっとした巧妙な perl のワンライナーを使ってその末尾の改行を「捨てる」こともできます……。 |
echo "Anthony" | perl -0777 -pe 's/\n$//' |\
magick label:@- label_stdin_4.gif
![[IM Output]](../static/img/text/label_stdin_4.gif)
他の API では、'パイプ open' 経由でテキストを IM コマンドに渡す前に、その末尾の改行を探すこともできます。
ユーザー定義のオプションエスケープ
大きな問題は、ある画像からのエスケープされた情報を、別の "[label:](#label)" や "[caption:](#caption)" 画像を生成する場合のように、何か別の画像で使おうとすることです。これは非常に難しい問題で、現在の解決策は(単一の画像については)、処理中の画像に付加される特別な「ユーザーオプション」を作成することです。この「設定」は、必要なときに "[label:](#label)"、"[caption:](#caption)"、"[-annotate](https://imagemagick.org/command-line-options/#annotate)" によって、パーセントエスケープシーケンスとして参照できます。たとえば、ここでは組み込みの rose 画像の情報を使って、まったく新しいラベル画像を作成します。その情報源の画像はその後で削除されますが、新しいラベルを元の画像に append するのも同じくらい簡単にできます。 |
magick rose: \
-set option:roseinfo 'rose image\nsize = %w x %h\nwith %k colors' \
label:'%[roseinfo]' -delete 0 label_escape.gif
![[IM Output]](../static/img/text/label_escape.gif)
はい、上記は巧妙ですが、それは関わっている IM コアライブラリ内部のいくつかの制限のためです。詳しくは 他の画像のデータへのアクセス を参照してください。
エスケープのエスケープ
IM に文字列を引数として(特に API 呼び出しとして)渡さなければならないが、IM にエスケープを展開させたくない場合は、追加のバックスラッシュ '\' を使って 3 種類のエスケープすべてを単純に「エスケープ」できます。'@' は先頭の文字である場合にのみ「エスケープ」する必要があり、また後方互換性のために、パーセントエスケープはそれを二重にすることでもエスケープできます。つまり、'%%' は単一のパーセントを生成します。たとえば……。 |
magick -background lightblue -fill blue -font Candice -pointsize 48 \
label:'\@ \\n \% 5%% ' label_escapes.gif
![[IM Output]](../static/img/text/label_escapes.gif)
| IM バージョン 6.3.2 より前は、'ファイルから読み込む' 機能を無効にするために、先頭の '@' をバックスラッシュでエスケープすることはできませんでした。その場合、先頭の '@' をエスケープする唯一の方法は、それをファイルから読み込むことでした。これは API ではあまり実用的ではありませんでした。
---|---
ここに、"[-annotate](https://imagemagick.org/command-line-options/#annotate)" についての同様の「エスケープをエスケープする」例を示します……。 |
magick rose: -fill white -stroke black -font Candice -pointsize 20 \
-gravity center -annotate 0 '\@ \\n 5%%' annotate_escapes.gif
![[IM Output]](../static/img/text/annotate_escapes.gif)
もちろん、前に示したとおり、('@' エスケープを使って)ファイルからテキストを読み込むことは、特別な意味を一切持たない文字どおりのものとして常に扱われます。これによってテキストの前処理が不要になり、IM に使わせたいテキストをそのまま書くだけで済みます。末尾の改行にだけ気をつけてください。 |
echo -n '@ \n 5%' |\
magick rose: -fill white -stroke black -font Candice -pointsize 20 \
-gravity center -annotate 0 '@-' annotate_escapes_file.gif
![[IM Output]](../static/img/text/annotate_escapes_file.gif)
言い換えると、ファイルから読み込む場合は、ものごとをエスケープする心配をする必要はなく、IM に使わせたいテキストをそのまま書けばよいのです。
古いバージョンの IM でのエスケープ
上記の定義は IM バージョン 6.3.3 で初めて最終決定されました。これより前は、IM ユーザーから送られた要望・問題・苦情に応じて、エスケープは一部のオプションでは扱われ、一部では扱われませんでした。これは特に "[label:](#label)" と "[caption:](#caption)" のパーセントエスケープに関して当てはまり、一時期それらは「無意味」とみなされていました。たとえば、次のラベル画像で '%c' が見えるかどうかは、(少なくとも IM v6.3.3 より前では)バージョンに大きく依存します。 |
magick -background lightblue -fill blue -font Candice -pointsize 48 \
label:'ab%cde' label_percent.gif
![[IM Output]](../static/img/text/label_percent.gif)
'abde'(パーセントエスケープが適用された)と 'ab%cde'(パーセントが適用されなかった)のどちらが見えるかは、お使いの IM のバージョンによります。 | _IM v6.2.4 では、パーセントエスケープは無意味であるとして "[label:](#label)" と "[caption:](#caption)" から削除されました。
しかしそれらは IM v6.3.2 で、任意の画像を参照できる新しい '%[fx:...] 構文として戻ってきて、テキスト→画像ジェネレータでのパーセントエスケープを再び有用にしました。FX 式エスケープ を参照してください。_
---|---
この「何がエスケープされるか」は、ファイルからのエスケープの扱いに関しても問題でした。IM v6.3.3 より前は、次のものは単一の行ではなく 2 行を生成していたでしょう。 |
echo -n ' Love \n/ Hate ' |\
magick -background lightblue -fill blue -font Ravie -pointsize 18 \
label:@- label_escapes_file.gif
![[IM Output]](../static/img/text/label_escapes_file.gif)
エスケープの扱いはバージョンによって大きく異なるので、v6.3.3 より古い IM では、スクリプトが自身のエスケープの扱いをテストし、プログラムの正しい動作にとって重要なら自身を調整することをお勧めします。誰か IM スクリプト用の自動テストを作成したい方がいれば、ぜひ貢献してください。あるいはそうしたテストを見つけたら、教えてください。
Pango -- 基本的な整形済みテキスト
"pango:" テキストコーダ(IM v6.7.6-3 以降で完全に動作)は、Label や Caption のコーダとほぼ同じように動作します。これは、「Pango」がインストールされているシステム上で、限定的なテキスト整形言語を提供します。Linux と MacOSX のシステムでは pango は標準ですが、Windows ではオプションです。ここに、特別な pango 整形を一切使わない簡単な例を示します……。 |
magick -background lightblue pango:"Anthony Thyssen" pango.gif
![[IM Output]](../static/img/text/pango.gif)
ただし、前述の テキスト属性 の一部は、基本的にはその整形要件のために、pango では機能しないことに注意してください。たとえば、"[-background](https://imagemagick.org/command-line-options/#background)" の色は設定できますが、デフォルトの fill、undercolor、使用する特定のフォントは設定できません。これは、これらの属性が代わりに Pango Markup Language 経由で選択できるからです(後述)。"[-size](https://imagemagick.org/command-line-options/#size)" を使って出力画像の幅と高さの制限を定義することをお勧めします。これに合わせて pango が入力テキストを自動的にワードラップ(中国語の場合は文字単位でラップ)します。 |
magick -background lightblue -size 150 \
pango:"Anthony Thyssen is the main author of IM Examples" \
pango_size.gif
![[IM Output]](../static/img/text/pango_size.gif)
さらに、Define の "pango:justify" を使って、Pango にテキストを適切に「両端揃え」させることさえできます……。 |
magick -background lightblue -size 150 -define pango:justify=true \
pango:"Contributions to IM Examples are welcome via the IM Forum." \
pango_justify.gif
![[IM Output]](../static/img/text/pango_justify.gif)
ただし、テキストは両端揃えできるものの、スペースや改行はテキスト整形ツールによって依然として考慮される点に注意してください。また、pango は(label や caption とは異なり)TAB の使用を理解します。 |
printf "col1\tcol2\nabc\txyz\n123\t789" |\
magick -background lightblue pango:@- pango_tabs.gif
![[IM Output]](../static/img/text/pango_tabs.gif)
| 上記の "printf" コマンドは '\t' エスケープを使ってタブ文字を生成できますが、IM はそうしたエスケープの使用を理解しないことに注意してください。ただし、文字列内の '\n' エスケープシーケンスは理解します。
---|---
しかし、TAB を使って列を生成するのはあまりうまくいきません。API の外で「タブストップ」を簡単に定義できないからです。そのため、この方法で TAB を使うことは、行や段落のインデント以外には お勧めしません 。
Pango マークアップ言語
しかし pango の真の力は、デフォルトで有効になっている「Pango マークアップ」言語にあります。"-define pango:markup=false" を使って pango マークアップを無効にできますが、そうするくらいなら Caption を使ってもよいでしょう。「Pango マークアップ」は HTML によく似ていて、テキスト中に隠した "<...>" マークアップタグの一式を使って、テキストをどう整形するかを制御します。ここにマークアップ言語のガイドをいくつか示します(API のゴミ抜きで)
- The Pango Markup Language
- Pango Text Attribute Markup Language (Gnome より)
- Pango Text Attribute Markup Language (GTK より)
- Pango Script Gallery(例)
たとえば……。 |
magick -background lightblue -gravity center -size 180x \
pango:"The <b>bold</b> and <i>beautiful</i>" \
pango_formatting.gif
![[IM Output]](../static/img/text/pango_formatting.gif)
"<span ... >" タグは、pango マークアップで使う主要なタグです。これによって、含まれるテキストの正確なサイズ・色・位置を制御できます。たとえば……。
magick -background lightblue \
pango:' Some <span size="49152" rise="-20480"
foreground="red" background="blue"
> Big Red on Blue </span> Text ' \
pango_span.gif
ほとんどの数値は 1024 倍されることに注意してください。そのため、上記の例の "size="49152"" の値は、48 ポイントのテキストポイントサイズを意味します。一方、負の rise("rise="-20480"")はテキストの位置を 20 ポイント(または 72 dpi では 20 ピクセル)下げることを意味します。しかし、テキストにポイントサイズを指定する代わりに、"size="x-large"" のような特別なサイズラベルを使うこともできます。次の例のソースコードを見てください。上記のクォートの中のクォートに注意してください。タグ内のクォートは必須です。ただし、タグ内の改行や余分なスペースは、テキストの整形に何の役割も果たしません。そのため、余分な改行をマークアップタグ内や、マークアップコメント "<!-- ... -->" 内に隠すと、とても便利なことがあります。これも次の例のソーステキストを見てください。pango 整形の力の最後の例として、ここでは事前に用意したファイル "[pango_test.txt](../static/img/images/pango_test.txt)" の整形にそれを使います。これには、使う可能性が高い一般的な pango マークアップタグのほとんどが含まれています。このマークアップファイルを、下の結果画像と比べてみてください。
magick -gravity center pango:@pango_test.txt pango_test.png
Pango の注意点と問題
- グラビティ
- pango で 1 行のテキストだけを選択的に中央揃えにすることはできませんでした。"
[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定では、すべてを中央揃えにするか、何も中央揃えにしないかしかできません。この理由は、pango がアプリケーション用の別々のテキストラベルを生成するよう設計されているためのようです。つまり、タイトルは通常、表示される本文とは別に生成されます。pango は、大規模なテキストページの整形エンジンを意図したものではありません。 - フォント
- pango はレンダリングの途中でフォントを変更できます。太字や斜体のテキストについては、すでに簡単にそうしています。しかし、フォントの指定は GTK 由来であり、そのため ImageMagick 一般とは異なるシステムを使います。GTK を使ったフォントについては、"gtk-demo" プログラムを実行し、「Pickers」と「Text Widget」をダブルクリックすることで、より詳しく知ることができます。
- Defines
- pango のテキスト整形のさまざまな側面をグローバルに制御するために使える、たくさんの特別な Defines があります。これらは現在 Pseudo File Formats に列挙されていますが、私自身、それらすべてを探求したわけではありません。私が使ったのは次のものです……。
-define pango:markup=false- マークアップ言語タグを無効にします。タグはそのまま出力に含まれます。テキスト内での pango 整形は一切できなくなります。これは特にデバッグに便利で、pango が入力として何を見ているかを正確に見られます。
-define pango:justify=true- 画像サイズの幅いっぱいにテキストを両端揃えします。つまり、テキスト行のブロックの左右の端が揃うように、単語間に余分なスペースを加えます。
Pango に関するさらなる情報
| 何が可能かを見るには Pango Script Gallery を参照してください。pango で何か面白いことをしたら、ぜひ貢献してください。私にメールするか(アドレスはページのフッターにあります)、IM Discussion Forum に投稿してください。 | pango がインストールされているシステムでは、"pango-view" コマンドを使って pango 整形済み画像を生成することもできます。ただし、そのデフォルトの 'density' つまり 'dpi' 設定はお使いのディスプレイの値です(IM はデフォルトで 72 dpi を使用)。そのため、ホストごとに異なることがあります。 |
|---|---|
Text -- プレーンテキストのページ
"text:" 入力形式は、プレーンテキストを、テキスト 1 ページにつき画像 1 枚からなる画像に「マジック」するよう設計されています。これは ImageMagick の「ページ化テキスト」入力演算子です。言い換えると、その目的は、プリンタがプレーンテキストを別々の紙片に印刷するのとほぼ同じ方法で、大きな整形済みテキストファイルをページに「マジック」することです。 | _"text:" ファイル入力形式を、似た "[txt:](files.html#txt)" 入力形式と 混同しないでください。後者は、まずファイルを 'IM ピクセル列挙' 画像形式として読み込もうとします。
だからといって、".txt" 付きのプレーンテキストファイルが失敗するわけではありません。実際、そうしたファイルはおそらく期待どおりに変換されます。なぜなら、列挙された画像が認識されない場合、"[txt:](files.html#txt)" ファイル形式は自動的に "text:" 形式にフォールバックするからです。
_
---|---
しかし、このようにテキストを扱うことには、いくつかの問題がありました。第一に、テキストは大きなキャンバスに描画されるので、不要な空白を取り除く問題が残ります(その空白が望ましくない場合)。もうひとつは、行は「ワードラップ」されず、長すぎる場合はキャンバスからあふれて切り捨てられることです。そして最後に、非常に長いテキストファイルでは、いくつかの追加の予防策を取らない限り、複数のページ(画像)が生成されます。一方、"text:" は、生成される最終的な画像サイズを変更したり、非常に長い行をワードラップしたりすることなく、ほぼあらゆるテキストファイルを扱えます。また、コマンドラインでテキストを使う場合のように、特殊文字を前処理する必要もありません。最後に、より重要なのは、固定幅フォント(Courier など)が使われる場合、間隔をあけた列状のデータを持つファイルは、依然としてそのデータを間隔をあけた列状に保持することです。基本的に "text:" は入力ファイルを「そのまま」画像に「マジック」します。 | _ファイルから読み込んだ入力テキストデータは、本質的に、UTF テキストを描画するためにフォントライブラリに直接渡されます。その結果として、一部の制御文字が普通でない「グリフ」で描画されることがあります。これには TAB と FORMFEED 文字が含まれ、これらは本稿執筆時点で 'freetype' ライブラリが誤って扱います。
これが気になる場合は、"expand" のようなフィルタプログラムを使ってテキストファイルを前処理し、TAB 文字を適切な数のスペースに「マジック」したいかもしれません。_
---|---
テキストを描画するとき、大きな「レター」サイズのページ(または "[-page](https://imagemagick.org/command-line-options/#page)" で指定したページサイズや種類)が、現在の解像度("[-density](https://imagemagick.org/command-line-options/#density)" で設定)で作成されます。デフォルト(72 dpi)では、これは '612x792' ピクセルのサイズになり、ほとんどの用途では非常に大きいものです。たとえば、ここに "magick" コマンドのプレーンテキスト整形済みマニュアルを、画像に直接変換したものを示します(大きいので、右側の 'page' 画像を選択すると見られます)……。 |
man magick | col -b | expand | \
magick -font CourierNew text:- -delete 1--1 text_manpage.gif
| _ただし、上記のマニュアル→画像変換は複数のページ(画像)を生成するので、私は 2 枚目以降を 削除 して、ページの GIF アニメーションではなく、最初のページだけが残るようにしました。
'[0]' という 読み込み修飾子 を入力ファイル名に付加して、たとえば "text:-'[0]'" のようにして、最初に生成された画像だけを読み込むよう IM に指示することもできました。ただし現時点では、すべてのページ選択は、全ページを生成してから不要なページを削除することで処理されています。_
---|---
印刷ページに存在する文字間隔の整形を保つために、上記では意図的に「固定幅」フォント 'CourierNew' を使いました。この出力が、上記の caption: の出力とどう違うかに注目してください。この画像の全体的な見た目は、次の ポストスクリプト セクションで示すのと同じ手法を使ってさらに改善できます。たとえば 'A5' ページが 100 dpi でどのくらいの大きさかを知りたいだけなら、このコマンドはそのサイズの 1 枚の空白ページを生成し、そのサイズをピクセルで返します。ファイル名 "/dev/null" は、常に空である特別な UNIX ファイルです。
magick -page A5 -density 100 -units PixelsPerInch text:/dev/null \
-format 'Page Size at %x = %w x %h pixels' info:
テキストページのトリミング
テキストは大きなキャンバスに「描画」されるので、生成される不要な空白をすべて取り除きたくなるでしょう。これは、画像操作 "[-trim](https://imagemagick.org/command-line-options/#trim)"、"[+repage](https://imagemagick.org/command-line-options/#repage)" を使い、それから見栄えをよくするために "[-border](https://imagemagick.org/command-line-options/#border)" を使って端の空白をいくらか追加することで行えます。もちろん、使った "[-background](https://imagemagick.org/command-line-options/#background)" 色を、再追加する "[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)" に合わせる必要もあります。複雑そうですか?実はそうでもありません。たとえば……。
echo " Hello Cruel World " |\
magick -background lightblue -fill blue -pointsize 18 \
text:- -trim +repage -bordercolor lightblue -border 3 \
text_trimmed.gif
上記の例では、"[-trim](https://imagemagick.org/command-line-options/#trim)" を使って "text:" ページ画像の膨大な余分な空白を取り除いています。ただしこれは、行頭の先頭スペースも取り除いてしまいます!しかし、入力中の先頭・末尾スペースを含めて、ページに実際に描画されたテキストのサイズまで画像を "[-trim](https://imagemagick.org/command-line-options/#trim)" できる興味深い手法があります。これは特別な "[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" 設定(後で詳しく見ます)を使います。
echo " Hello Cruel World " |\
magick -background white -undercolor lightblue -fill blue \
-pointsize 18 text:- -trim +repage \
-bordercolor white -border 3 text_boxed.gif
テキスト下部の余分な空白は、テキスト入力の最後の「改行」文字の結果で、画像に余分な空行を作っています。しかしご覧のとおり、入力テキストの先頭・末尾スペースは保たれました。上記で透明な背景色を使えば、トリミングされた画像を flatten して、描画されていない領域を、使用した 'undercolor' と同じ色に「マジック」できます。
echo " Hello Cruel World " |\
magick -background none -undercolor lightblue -fill blue \
-pointsize 18 text:- -trim +repage \
-bordercolor lightblue -border 3 \
-background lightblue -flatten text_box_trimmed.gif
上記の結果は(追加した "[-border](https://imagemagick.org/command-line-options/#border)" を除けば)、IM が今では "[label:](#label)" を使い、'@' エスケープされたファイル名から読み込んで生成するものと、実際にはほぼまったく同じです。ただし "[label:](#label)" は、それをより速く、はるかにきれいな方法(ポストスクリプト変換ではなく "freetype" ライブラリ経由)で行います。"[-page](https://imagemagick.org/command-line-options/#page)" サイズは、ピクセルで(次の例を参照)、あるいは('A5' のような)媒体ページサイズを使って、"[-density](https://imagemagick.org/command-line-options/#density)" つまりピクセル解像度設定を使って、より小さく指定できます。また、ページ上でテキストの描画を開始するオフセットを、左上隅を基準に指定することもできます。たとえば……。
echo "This is a long line that shows that 'text:' does not word wrap." |\
magick -background lightblue -pointsize 18 \
-fill blue -page 320x95+50+10 text:-'[0]' +repage text_page.gif
| _ほぼすべての他の画像作成演算子は、"[-page](https://imagemagick.org/command-line-options/#page)" 設定を使って、より大きな仮想「キャンバス」と、そのキャンバス上の画像の「オフセット」を設定します。一般的には画像をレイヤー化したり、アニメーションを生成したりする目的です。このため、"text:" や "ps:" 操作の後は、"[+page](https://imagemagick.org/command-line-options/#page)" を使ってページ設定をリセットするのがおそらくよい考えです。さもないと、同じコマンドライン上で後から読み込む二次的な画像で、予期しない結果になるかもしれません。
これが、上記の例に "[+repage](https://imagemagick.org/command-line-options/#repage)" 演算子を追加した理由でもあります。さもないとテキストがオフセットされ、生成される画像もオフセットされてしまうのです!
このオフセットの使用の詳細については、ページ画像属性 を参照してください。
---|---
最後の例で、ページの幅に収まらないほど長いテキスト行はページからあふれ、「ラップ」されないことに注目してください。これは事実上、行末をクロップして捨ててしまいます。また、行が多すぎる場合は、"text:" は _複数のページ を生成し、したがって 複数の画像 を、テキストファイルのポストスクリプト変換によって生成されるページごとに 1 枚ずつ生成します。テキストの最初のページだけに関心があるか、複数画像になる可能性を避けたいだけなら、"text:" ファイル名に '[0]' を追加して、テキストが画像に変換された 後で、最初に生成されたページだけを読み込むよう IM に指示してください(前の例を参照)。
Postscript/PDF -- 整形済みのテキストとグラフィックの入力
(または他のベクター画像形式)
以下は、"PS:"(ポストスクリプト)画像だけでなく、ベクターグラフィックスを使って扱われる他のすべての画像にも使える、標準的なベクター画像の扱いの手法を示します。これには次のような画像形式が含まれます。"PDF:"(portable document format)、"[TEXT:](#text)"(ページ化プレーンテキスト)、さらには "[SVG:](draw.html#svg)"(scaled vector graphic)や "[WMF:](formats.html#wmf)"。この方法を拡張すると、テキストが画像としてどう見えるかを非常に細かく制御できます。たとえば、適切な「テキスト→ポストスクリプト」フィルタを使えば、ポストスクリプト画像でのワードラップ・両端揃え・複数フォントの扱い・太字化・枠線・タイトル・ファイル名・日付などの装飾を制御できます。ただし、このセクションはテキスト→画像についてなので、まずテキストを整形済みポストスクリプトファイルに「マジック」する必要があります。これを行うのに使える外部プログラムがたくさんあります。たとえば "a2ps"、"enscript"、"pstext" などです。本質的には、ワードプロセッサ('OpenOffice' や 'Word'、あるいは 'Notepad' でさえ)を使えますし、バッチ式のテキスト処理システムが欲しければ 'TeX' や 'LaTeX' を使って整形済みテキストを生成できます(後述の 完全なテキスト処理システム を参照)。これらのプログラムはすべて、プレーン・太字・異なるサイズ・フォントのテキストを混在させる複雑さを、ワードラップ・両端揃え・段落の制御とともに扱うよう設計されています。これらのプログラムの出力を IM に渡して、望むサイズと品質の画像に変換できます。では、まずいくつかポストスクリプトを生成しましょう(個人用の fortune プログラムからテキストを変換)。 |
mesgs LN-ManKzinWars | \
a2ps -q -1 --rows=10 --prologue=bold \
--center-title="Postscript via 'a2ps'" \
--header='' --left-footer='' --right-footer='' \
-o ps_version.ps
さて、それを画像に「マジック」して、結果をトリミング(上記の "text:" の例のように)して、デフォルトで生成されるページ/キャンバスから余分な空白領域を取り除けます。
magick ps_version.ps'[0]' \
-trim +repage -bordercolor white -border 3 ps_version_raw.gif
入力を最初のページだけに制限する '[0]' の使用に注目してください。ポストスクリプト画像が複数のページを生成する場合でも、それは "ghostscript" デリゲートによって完全に処理されますが、IM はページごとに複数の画像を生成するのではなく、最初に返された画像だけを読み込みます。ポストスクリプトが非常に大きい場合は、IM と "ghostscript" で処理する前に、他のポストスクリプトユーティリティを使ってページ数を制限したいかもしれません。ご覧のとおり、デフォルトの "[-density](https://imagemagick.org/command-line-options/#density)" の 72 dpi に変換されたポストスクリプトは、しばしば本来あるべきほどよくは見えず、アンチエイリアスもごくわずかです。これは、こうした低解像度で動作するよう設計されていないポストスクリプトフォントを扱うときに特に当てはまります。これを改善するには、スーパーサンプリング の手法を使ってよりよい画像を生成できます。この場合、"ghostscript" により高い解像度(または画像の "[-density](https://imagemagick.org/command-line-options/#density)")でページを描画させます。それから "[-resample](https://imagemagick.org/command-line-options/#resample)"(特殊なリサイズ)して、このより大きな画像をより「通常の」画面解像度の density に戻します。
magick -density 196 ps_version.ps'[0]' -resample 72 \
-trim +repage -bordercolor white -border 3 ps_version.gif
値 '196' は最終的な 72 dpi の 3 倍で、これは "[-resample](https://imagemagick.org/command-line-options/#resample)" が使われるとき、おおよそ 3×3 ピクセルが各ピクセルにマージされることを意味します。これにより、テキストの端に沿ったアンチエイリアスのピクセルがよくなり、結果の全体的な見た目が改善されます。また、より大きな density や解像度を使うことは、単にフォントを拡大することとはまったく同じではないことにも注意してください。フォントの定義には、低解像度の状況を扱うための調整が含まれていることがあります。たとえば、2 つの画像で文字 'e' の穴を比べてみてください。元の版はフォント内部の特別な処理のおかげでより鮮明ですが、全体的には後者のスーパーサンプリングした版のほうが明瞭です。詳しくは後述の 解像度、ポイントサイズ、そして実際のフォントサイズ を参照してください。上記の値を使う必要はありません。少し違う値のほうが、よりよい、あるいはより望ましい結果になることがあるからです。もちろん、"ghostscript" に 2 倍、3 倍、あるいは 4 倍も大きな画像を生成させるということは、IM が画像を生成するのに 4 倍、9 倍、16 倍も長くかかることも意味します!それだけ多くのメモリと一時ディスク容量も使います!しかし、その結果は一般に価値があります。一番よいのは、自分の文書で実際に試して、何が最良の結果になるかを見ることです。また、アンチエイリアスがもっと必要なら、さらに大きな入力解像度を使う代わりに、サイズを縮小する前に画像をサブピクセル単位でぼかしてみる(たとえば '-blur 0x0.7')こともできます。リサイズ後にごくわずかにアンシャープをかける(よくある photoshop の手法)と、全体的な最終結果が改善することがあるのも、ときどき経験しています。
magick -density 196 ps_version.ps'[0]' \
-blur 0x0.7 -resample 72 -unsharp 0x0.7 \
-trim +repage -bordercolor white -border 3 ps_unsharp.gif
ただし、これらの調整には注意してください。かえって悪くなることもあるからです。
白の代わりに透明な背景にしたい場合は、"[-channel](https://imagemagick.org/command-line-options/#channel)" 設定を 'RGBA' にして、画像にアルファチャンネルを含められます。もちろん、半透明の色を扱える画像形式を使う必要があります。
magick -channel RGBA -density 196 ps_version.ps'[0]' -resample 72 \
-trim +repage -bordercolor none -border 3 ps_transparent.png
バナーが、透明や半透明にされるのではなく、依然として背景にオフホワイト色を使っていることに注目してください。それは、生成されたポストスクリプトが実際にその背景を描画し、ページのデフォルト背景(白であれ透明であれ)を置き換えているからです。このように背景を透明にすると、ポストスクリプト画像を特定の背景色に重ねられるようになります。
magick ps_transparent.png -background skyblue -flatten ps_bgnd_color.gif
アルファ合成の方法 を使えば、特定の背景画像やタイル状の背景に重ねることさえできます。
magick composite -tile bg.gif ps_transparent.png -compose DstOver \
ps_bgnd_tiled.gif
ほぼすべてのポストスクリプトプリンタは紙やオーバーヘッド透明シートを暗くすることしかできない(これにはカラープリンタも含まれます)ので、上記が印刷されると、バナーは自動的に半透明になります。プリンタがするのと同じことを IM にもさせたい場合は、特別な '[Multiply](compose.html#multiply)' アルファ合成を使って、「白い背景」画像を、望む「紙」の背景に重ねられます。
magick composite -tile bg.gif ps_version.gif -compose Multiply ps_multiply.gif
カラーのポストスクリプト画像がある場合、特別な '[BumpMap](compose.html#bumpmap)' 合成方法を使って、色付きの紙への純粋な白黒プリンタもシミュレートできます。これは、画像をマルチプライで合成する前に、ソースのオーバーレイ画像をグレースケール化します。オーバーヘッド透明スライドのグレースケール画像版を生成することもできます。これは基本的に、(上記の)不透明な白い背景画像を「マスク」として使い、それで形状を整えた透明画像を設定します。アルファシェイプ演算子 を使います。
magick ps_version.gif -negate -background black -alpha shape ps_overhead.png
上記の "[text:](#text)" コンバータと同様に、"ps:" コンバータも "[-page](https://imagemagick.org/command-line-options/#page)" 設定を使って、ページが描画される画像「媒体」のキャンバスサイズを設定します。ただし、与えられたオフセットは無視されます。しかし、ほとんどのポストスクリプトファイルは描画媒体のサイズを内部で定義しているので、これは通常は不要です。 | _ほとんどの他の画像作成演算子は、"[-page](https://imagemagick.org/command-line-options/#page)" 設定を使って「仮想キャンバス」と、その仮想キャンバス上のオフセットを設定します(たとえば GIF アニメーションを生成するため)。そのため、"text:" や "ps:" 画像読み込み操作にそれを使った後は、"[+page](https://imagemagick.org/command-line-options/#page)" を使ってリセットするのがおそらくよい考えです。さもないと、後の画像で予期しない結果になるかもしれません。
このオフセットの使用の詳細については、ページ画像属性 を参照してください。_
---|---
最後の実践的な例として、私の Ray Traced Tetrahedron 画像を見てください。他の似た画像は Studies into Polyhedra で見られます。背景ページは、表示されている 3D 数学的オブジェクトを生成したのと同じデータから生成しました。テキストデータは "a2ps" を使って変換し、それから IM を使ってこれを画像に「マジック」しました。この画像の上に、同じ数学的オブジェクトの事前に用意した別の線画をページに追加しました。この最終画像('targa' つまり TGA 形式で保存)を "[PovRay](http://www.povray.org/)" レイトレーサーに渡して、最終画像つまりレイトレースされたシーンに取り込みました。
GhostScript を直接使う
これは厳密には IM ではありませんが、Richard Bollinger が、"ghostscript" デリゲートを直接実行するほうがはるかに効率的で、IM によるファイル処理が少ないため処理が桁違いに速くなる、と報告しています。たとえば、次を実行する代わりに……。
magick -density 300x300 -compress Group4 file.ps file.tif
GhostScript にそれを直接させられます。
gs -dBATCH -dNOPAUSE -sDEVICE=tiffg4 -r300x300 \
-sOutputFile=file.tif file.ps
これにより、IM が大きな一時ファイルを生成する必要(セキュリティとパイプライン化された画像処理のため)がなくなります。その結果、GhostScript を直接使うと、かなりのファイル処理と IO 処理を節約でき、ポストスクリプトや PDF ファイルを処理するときに大きなパフォーマンス向上を生み出せます。ただし "ghostscript" は画像をリサイズできず(出力 density や解像度を調整する以外には)、おそらく必要とする画像ファイル形式や、望む品質で画像を出力できないでしょう。しかし、その後で GhostScript の出力を ImageMagick に渡して、タスクを仕上げることはいつでもできます。つまり、特に結果をスーパーサンプリングしたい場合(より高解像度の入力を、より小さな出力にリサイズ)はそうです。GhostScript は、使い方を理解したり、特定の種類のポストスクリプト用に修正したりするのが難しいプログラムでありえます。Cristy は IM ユーザーのために絶えずこれらの問題と格闘していて、その点で彼は素晴らしい努力をしてきました。残念ながら、起こりうる(そして実際に起こる)多くのことに対処する中で、IM は GhostScript 経由のポストスクリプト/PDF のための単純化された方法を提供できません。
Draw -- 既存のキャンバスにテキストを描画する
低レベルの "[-draw](https://imagemagick.org/command-line-options/#draw)" 演算子を使ってフォントを描画すると、特にフォントの正確な位置や、フォントが描画される画像のサイズについて、はるかに多くの制御が得られます。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
-fill blue -draw "text 25,65 'Anthony'" text_draw.gif
ただし、これを使うには、フォントを描画する適切なサイズの背景画像を生成する必要があり、未知のテキストを描画する場合はこれが厄介になりえます。この問題を解決する方法については、フォント画像の自動サイズ調整 を参照してください。標準的なテキストオプションを超える多くの追加オプションも、"[-draw](https://imagemagick.org/command-line-options/#draw)" が画像にテキストを実際にどう描画するかに影響します。"[-fill](https://imagemagick.org/command-line-options/#fill)" 色を指定できるだけでなく、"[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" や、エッジつまり "[-stroke](https://imagemagick.org/command-line-options/#stroke)" の色も指定できます。これらはどちらもデフォルトでは無効です(色 'none' に設定)。"[-fill](https://imagemagick.org/command-line-options/#fill)" 色は "[-tile](https://imagemagick.org/command-line-options/#tile)" 画像パターンで置き換えることもでき、ストロークのエッジ幅は "[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)" を使って変更できます。それから、描画されるテキストの相対位置は "[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定で変更できます。たとえば、ここでは今述べた追加機能の多くを使いました。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
-tile bg.gif -undercolor dodgerblue -stroke navy -strokewidth 2 \
-gravity center -draw "text 0,0 'Anthony'" text_options.gif
| _IM バージョン 6.2.4 以降、"[-draw](https://imagemagick.org/command-line-options/#draw) text" 操作は、改行を意味する '\n' の使用や、パーセント '%' 画像情報エスケープの使用を理解しなくなりました。(パーセントの描画バグ を参照)。
これらの能力と問題は、しかし、新しい IM v6 の演算子 "[-annotate](https://imagemagick.org/command-line-options/#annotate)" では引き続き利用できます。後述の Annotate テキスト描画演算子 を参照してください。_
---|---
上記のオプションはすべて、"[-draw](https://imagemagick.org/command-line-options/#draw)"(MVG -- Magick Vector Graphic)文字列内でも使えます。ただし、上記のオプションを draw 引数内で設定すると、そのオプションはその特定の draw MVG 文字列にのみ適用されます。さらに、draw MVG 形式はもっとずっと多くのこと、たとえばテキストの回転やフォントの「装飾」ができ、もちろん円のようなさまざまな形状を画像に描画することもできます。たとえば、ここでは下線付きで回転したテキストを、いくつかの背景の円の上に重ねて描画します。
magick -size 320x120 xc:lightblue \
-draw "fill tomato circle 250,30 310,30 \
fill limegreen circle 55,75 15,80 \
font Candice font-size 72 decorate UnderLine \
fill dodgerblue stroke navy stroke-width 2 \
translate 10,110 rotate -15 text 0,0 ' Anthony '" \
draw_mvg.gif
画像作成に "[-draw](https://imagemagick.org/command-line-options/#draw)" を最大限に活用したいなら、描画の例ページ を見ることをお勧めします。
アンダーカラーボックス
上で、そして後でも示すとおり、"[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" 色設定は、その文字とフォントについて定義された描画領域を着色します。一般的には、それは描画された文字にぴったり合うだけです。これは特に描画されたフォントの左右の端について当てはまります。上下の端は通常、すべての文字を収容できるほど十分に大きいからです。描画領域は基本的に、フォントが描画される領域を囲む文字「セル」の境界を表します。"[-undercolor](https://imagemagick.org/command-line-options/#undercolor)" オプションを使う主な用途は、テキスト周りの「ノイズの多い」背景をクリアする簡単で手早い方法としてです。たとえば 画像の上への注釈付け を見てください。ただし、その場合は描画する文字列の先頭と末尾に追加のスペース文字を加えることもお勧めします。
バウンディングボックスのあふれ
テキストを描画するとき、あるいは一般的にフォントを扱うときに、おそらく最も大きな問題に出くわすのは、すべてのフォントが通常のルールに従うわけではないことです。フォントのデザイナーは、個々の文字(つまり「グリフ」)を、現在のテキスト位置(キャレットとして知られる)を基準に、どこにでも「描画」できます。フォントの位置は前に進む必要すらなく、一部の国際的なフォントでは後ろに進むことさえありえます!この設計の自由の結果として、一部の「グリフ」は、フォントがその文字が収まると宣言している定義済みの描画領域に収まりません。特に斜体やスクリプト風のフォントでは、文字の一部が境界をはるかに超えて、後(や前)の文字が使う領域にはみ出します。この点で私が見た最悪のフォントは 'LokiCola' フォントで、その大文字の約半分を、個々の文字セルの境界をはるかに超える長い波打った尾を付けて描画します。このフォントは基本的に、各大文字の後に 3 文字以上の小文字が続くと想定しています。これを示すために、このフォントの大文字をいくつか別々に描画して、文字が「アンダーカラー」つまり描画境界をどれだけ超えてはみ出しうるかを見られるようにします。また、そのうちのいくつかを使ってフォント名を作り、それらが設計どおりに使われた様子と、なぜバウンディングボックスからあふれるのかを見られるようにします。
magick -size 500x200 xc:lightblue \
-font LokiCola -pointsize 72 -undercolor dodgerblue \
-draw "text 15,65 'L'" -draw "text 130,65 'C'" \
-draw "text 245,65 '1'" -draw "text 360,65 'H'" \
-gravity South -draw "text 0,10 'Loki Cola'" draw_undercolor.gif
Annotate -- テキスト描画演算子
IM バージョン 6 で、新しいフォント描画演算子 "[-annotate](https://imagemagick.org/command-line-options/#annotate)" が利用可能になりました。この演算子は多くの点で "[-draw](https://imagemagick.org/command-line-options/#draw) text" 操作を使うよりずっと単純ですが、'annotate()' API(Application Program Interface)を使うため、より強力でもあります。この演算子は "[-draw](https://imagemagick.org/command-line-options/#draw)" のプリミティブを使いますが、より複雑な方法で使います。たとえば、特別な エスケープ文字 を展開して追加の画像情報や複数行を加えたり、描画されたテキストに座標系変換を適用して傾斜や回転を生み出したりします。このため、この演算子は今やすべての ImageMagick のテキスト描画と画像注釈にとって推奨されるテキスト描画演算子となっており、これらの例ページにもそれが反映されています。ここに、この演算子を使った基本的な例を示します。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
-fill blue -annotate +25+70 'Anthony' annotate.gif
"[-annotate](https://imagemagick.org/command-line-options/#annotate)" 演算子の追加機能のひとつは、描画されたテキストの X 軸と Y 軸を、互いに完全に別々に回転できることです。これは、各軸を回転させる角度を、演算子の引数中の「画像サイズ」として与えることで行います。単一の "[-annotate](https://imagemagick.org/command-line-options/#annotate)" 操作がどれほど複雑になりうるかを示すために、ここにボックス付き・ストローク付き・傾斜した画像を示します……。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
-tile bg.gif -undercolor dodgerblue -stroke navy -strokewidth 2 \
-annotate 0x20+20+67 'Anthony' annotate_opts.gif
この例では、annotate の 4 つの引数すべてが与えられています。X 軸の回転、Y 軸の回転、そして背景画像上のフォントの X 位置と Y 位置です。また、("[-tile](https://imagemagick.org/command-line-options/#tile)" で設定した)塗りつぶしパターンも、フォントとともに傾斜していることに注目してください。それは、せん断/回転された座標系を使って描画され、それが描画されたテキスト内にタイル状に並べられた塗りつぶしパターンもせん断するからです。このせん断能力のさらなる例は、せん断された影付きフォント の例です。それを、同等の "[-draw](https://imagemagick.org/command-line-options/#draw)" MVG 文字列で作成した 傾斜フォント と比べてみてください。"[-annotate](https://imagemagick.org/command-line-options/#annotate)" のせん断操作の効果をまとめた表については、Annotate 引数の使い方 を参照してください。たとえば、ここにわずかに回転したテキストを示します……。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
-annotate 350x350+20+90 'Anthony' annotate_rotated.gif
| IM が正しく理解するには、"[-annotate](https://imagemagick.org/command-line-options/#annotate)" に与える角度が正でなければならないことに注意してください)。これの例外は、カンマ区切りの 4 つの数からなる ジオメトリ引数 の形式が使われる場合です。たとえば "-annotate '-10,-10,20,90' 'Anthony'" は、最後の例で使えたでしょう。
---|---
これを使って、角度の付いた縮約ラベルを生成できます。たとえば……。 |
magick -size 100x60 xc:skyblue \
-annotate 300x300+20+50 "First" \
-annotate 300x300+35+50 "Second" \
-annotate 300x300+50+50 "Third" \
-annotate 300x300+65+50 "Fourth" \
-annotate 300x300+80+50 "Fifth" \
annotated_labels.jpg
![[IM Output]](../static/img/text/annotated_labels.jpg)
エスケープ文字を使って、現在の画像に関する他の情報を注釈文字列に加えることもできます。たとえば、組み込みの "rose:" 画像を、その画像のサイズに関する情報で上書きしてみましょう。テキストを画像の中央に置くために "[-gravity](https://imagemagick.org/command-line-options/#gravity)" 設定を使い、'0' という "[-annotate](https://imagemagick.org/command-line-options/#annotate)" 引数を使って、あらゆる回転とオフセットを無効にします。 |
magick rose: -fill white -stroke black -font Candice -pointsize 20 \
-gravity center -annotate 0 '%wx%h\nPixels' annotate_rose.gif
![[IM Output]](../static/img/text/annotate_rose.gif)
詳しくは後述の テキスト引数における特殊エスケープ文字 を参照してください。テキストをより大きな画像にさまざまな方法で注釈する(たとえば横に中央揃えしたり、右下隅に回転したり)他の例については、実践的なテキスト注釈の例 を参照してください。
自動的にサイズ調整される注釈テキストのキャンバス
"[label:](#label)" が提供できる以上の制御が必要なことがよくあります。たとえば、タイルやグラデーション画像を使いたい場合、テキストを Annotate する必要があります。残念ながら、その場合、注釈テキスト に必要なキャンバスのサイズを事前に知る必要があります。ここに、その問題の典型的な例を示します。最初にこのコマンドを設定したとき、サイズを望む結果に設定し、最初はかなりうまくいきました。しかし、こうなりました……。
magick -size 480x80 gradient:yellow-green \
-font ArialBkI -pointsize 70 -tile gradient:blue-red \
-annotate +10+65 'Gradient Fun' funfont_gradients.jpg
残念ながら、キャンバスサイズを当て推量したとき、上記で 'Gradient' という単語を綴り間違えていました(文字 'i' が抜けていた)。もちろん、その綴りを直したとき、画像サイズが今度は間違ったものになり、上記の不正確な結果が生じました。私たちに必要なのは、"[-annotate](https://imagemagick.org/command-line-options/#annotate)" 演算子を使いつつ、キャンバスを 注釈テキスト に合わせてサイズ調整できることです。ひとつの解決策は、はるかに大きなキャンバスを使い、それから背景を正しいサイズに "[Trim](crop.html#trim)" することです。見栄えをよくするために、フォントと画像の最終的な端の周りに少し余分なスペースを加える "[Border](crop.html#border)" も追加しました。
magick -size 800x120 xc:black -font Corsiva -pointsize 100 \
-tile tile_disks.jpg -annotate +20+80 'Psychedelic!' \
-trim +repage -bordercolor black -border 10 funfont_groovy.jpg
この方法は、最終的な画像がどれくらいの大きさであるべきかを当て推量しようとするよりずっとよいのですが、"[キャンバスのトリミング](crop.html#trim)" は、タイル状の多色背景をトリミングしません。よりよい解決策は、"[label:](#label)" を使って正しいサイズのキャンバスを生成することです。それから Draw Color Fill を使って、キャンバス(とラベルテキスト)の上に画像をタイル状に並べ、最後に別のタイリング画像を使ってテキストを Annotate します。
magick -font Ravie -pointsize 72 label:'Get Wet!' -border 10 \
-tile tile_aqua.jpg -draw "color 0,0 reset" \
-tile tile_water.jpg -gravity center -annotate +0+0 'Get Wet!' \
autosize_wet.jpg
| 中央揃えの "[label:](#label)" 画像中のテキストの位置は、中央揃えの "[-annotate](https://imagemagick.org/command-line-options/#annotate)" 操作の位置と正確には一致しないことがある点に注意してください。2 つの方法はまったく異なる処理アルゴリズムに従うので、特に普通でないフォントが関わるときには一致しないことがあります。
---|---
'アンダーカラーボックス' を使った自動サイズ調整
"[label:](#label)" 画像を使う代わりに、アンダーカラーボックス と 大きなストローク幅 を使ってフォントを大きなキャンバスに描画し、それからキャンバスを合うようにトリミングできます。たとえば
magick -size 500x100 xc:lightblue -font SheerBeauty -pointsize 72 \
-gravity center -undercolor white -stroke none -strokewidth 3 \
-annotate +0+0 ' Invitation ' -trim +repage -shave 1x1 \
invitation_box.jpg
フォント周りのスペースの量は、"[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)" 設定を使って調整できます。唯一の重要な要件は、最初のキャンバスが背景色(この場合は 'lightblue')と異なる色であり、最終的な結果より大きいことです。ひとつ注意ですが、一部のフォントは個々の文字の描画領域のはるか外側に文字を描画します。(たとえば上記の アンダーカラーボックス を参照)。この場合、上記の結果は機能しますが、透明なキャンバスを使い、それから結果を白の上に重ねる(たとえば "-background white -flatten" のような操作を使って)必要があるかもしれません。それで、使われていないまだ透明な領域を白に「マジック」します。ただし、その文字はおそらく結果画像の端に触れているでしょう。基本的に、すべての状況で勝てるわけではないので、ただ最善を尽くしてください。
グレースケールのテキスト画像を着色する
上記の画像は意図的にグレースケールの白黒画像として生成しました。これはマスキングのテンプレートとして使えるからです。このような純粋な画像から、画像の背景と前景を、別々に、あるいは両方同時に着色できます。たとえば、ここでは 色による Level 演算子、"[+level-color](https://imagemagick.org/command-line-options/#level-color)" を使って、前景と背景の色に特定の値を割り当てるよう、画像の色をグローバルに変更します。
magick invitation_box.jpg -colorspace sRGB \
+level-colors navy,lightblue invitation_colored.jpg
たとえば、ここでは 合成マスキング を使って、背景と前景をパターン画像で置き換えます。
magick invitation_box.jpg -colorspace sRGB \
\( +clone -size 300x150 -tile gradient:LightYellow \
-draw "color 0,0 reset" \) \
\( +clone -size 300x150 -tile plasma:tomato \
-draw "color 0,0 reset" \) \
-reverse -composite invitation_rose.jpg
上記の Reverse 演算子 は、画像を並べ替えて、最初の画像が合成の 3 番目の「マスキング」画像になるようにするために使われています。すると前景("plasma:")画像が最初になり、背景が真ん中になります。このようにグレースケール画像を着色する他の手法については、マスクを使って合成領域を制限する を参照してください。より一般的には 画像でのマスクの使用 を参照してください。タイル用のグラデーションを生成する他の方法については、色のグラデーション、まばらな色の点、ランダム化されたキャンバス を参照してください。
フォント
工事中
フォントパスの順序付けについては、それは単に XML ファイルで指定されたフォントの順序付けです。
開始点はシステムフォントで、それに続いてシステムにインストールされた
"type.xml" ファイルです。私のシステムでは、これは "/etc/ImageMagick-6/type.xml" です。
このシステムにインストールされた "type.xml" ファイルは、通常、単に他の type-* ファイルを
'include' するリストです。そして include の順序が、追加のシステムフォントと
Ghostscript フォントの順序を指定します。
そのファイルの後、'home' ディレクトリや、現在のディレクトリにさえある
他の "type.xml" ファイルが探されます。
後のフォントは前のフォントを置き換えません。そのため、2 つのフォントが同じ名前を持つ場合、
最初のものだけが IM に認識されます。(セキュリティ上の対策です)。
読み込まれたフォントを見るには
magick -list font
を使います。
各フォントリストが見つかった type ファイルの "Path:" を列挙しますが、
パスは逆順で列挙され、システムフォントが末尾に来ます。
たとえば私には "Courier" という個人用フォントがありますが、上記のリストには
列挙されません。なぜなら、それは「システムフォント」領域で見つかった "Courier"
(上記の出力の末尾に列挙されています)の後に定義されたからです。
一方、私自身の個人用フォント "CourierNew" は列挙されます。なぜなら、それはどの
システムやシステム設定で定義されたフォントとも衝突しないからです。
特定の要求に対してどのフォントグリフファイルが選択されるかを見るには
次を使います……。
magick -debug annotate xc: -font Courier \
-annotate 0 'Test' null: 2>&1 |
grep '^ *Font '
API を使わずにフォントメトリクスを求める
特定のフォントと、その個々の文字には、たくさんの情報が含まれています。そうした情報は持っていると非常に便利でありえます。特に、多くの異なるフォントのテキストをつなぎ合わせるために IM を使いたい場合はそうです。また、ほとんどのフォントはプロポーショナルフォントであることを覚えておくことも重要です。つまり、個々の文字はそれぞれ異なる幅を持ち、キャレット(つまり原点)の異なる「自然な」前進量を持ちます。そのため、特定の文字の「文字列」はそれぞれ、使われた文字の実際の数とはほとんど無関係に、異なる長さでレンダリング(描画)されます。これの例外は「固定幅」フォントで、"Courier"、"Typewriter"、"Terminal" フォントなどです。これらではすべての文字が同じ幅を持ち、テキストの列を簡単に生成できます。デバッグ設定 "[-debug](https://imagemagick.org/command-line-options/#debug) annotate" を使って、特定の文字列について、TTF フォントのメトリクスを IM に直接報告させられます。たとえば……。
magick -debug annotate xc: -font Candice -pointsize 24 \
-annotate 0 'Test' null: 2>&1 |\
grep Metrics: | fmt -w80
| ご覧のとおり、使える雑多な情報が得られます。原点を基準とした、描画された文字列の宣言された境界(これは必ずしも文字列の実際の境界ではありません)から、次の文字列を描画する前に「キャレット」(原点)が前進すべき量まで。完全なデバッグ出力(かなり冗長で、上記には示していません)は、実際に使われたフォントファイルも(2 回)報告するので、正しいフォントを使っているかの確認にも使えます。 | "[-debug](https://imagemagick.org/command-line-options/#debug) annotate" メソッドは IM v6.3.9-2 で追加されました。 |
|---|---|
古い手法
しかし、このデバッグ出力は便利でないかもしれませんし、このバージョンより古い IM を扱わなければならないかもしれません。以下は、テキストを実際にさまざまな方法と色で描画し、結果画像から(整数として)情報を抽出する古い例です。たとえば、72 ポイントで、固定されたベースラインを基準にした 'Ravie' フォントの寸法を調べてみましょう。ここに、参考として、これから調べる画像を示します。これを画像として描画して保存する必要は実際にはありません。なぜなら、抽出するのは画像ではなくデータだけだからです。この画像の色は変更され、"[-trim](https://imagemagick.org/command-line-options/#trim)" を使って、使われたメトリクスを抽出するために、白と黒の部分を別々に見られるようにします。 |
magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
-fill black -undercolor white -annotate +20+100 'A' font_drawn.gif
![[IM Output]](../static/img/text/font_drawn.gif)
基本的なフォントメトリクスのために、まずフォント自体を透明な色('None')で描画して、この特定のフォントの、この特定の文字のバウンディングボックスつまり描画領域のサイズと位置を測って見つけられるようにします。高さの情報のためには、ただ何でも描画すればよいことに注意してください。
magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
-fill none -undercolor white -annotate +20+100 'A' -trim info:
上記の結果から、72 ポイントの 'Ravie' フォントは、バウンディングボックスの総高さが 74 ピクセルになることがわかります。ボックスの上端は画像の上端から 42 ピクセルです。ベースラインは y 座標 100 ピクセルに配置されていたので、ボックスは 100 − 42 つまりベースラインの 58 ピクセル上から始まります。それで、ディセンダー用にベースラインの下のバウンディングボックスは 74 − 58 つまり 16 ピクセル残ります。 |
すべてのフォントが、その定義された描画バウンディングボックス内に描画を制限するわけではないことに注意してください!一部の文字はそれらの境界のはるか外側にはみ出すことがあります。それが、上記の例が "[-fill](https://imagemagick.org/command-line-options/#fill)" 色を 'none' に設定する理由です。そうすれば、行儀の悪いフォントが上記の測定に影響しません。 |
|---|---|
また、行(実際にはベースライン)を隔てる距離は、純粋にフォントのポイントサイズによって決まるべきで、フォントがどう描画されるかとは何の関係もないことに注意してください。私たちの例では、フォントのポイントサイズが 72 ポイントで、1 ポイントは 1/72 インチと定義されているので、ベースラインは 1 インチ離れているはずです。現在の出力解像度(density)が 1 インチあたり 72 ピクセルなら、それはベースラインが 72 ピクセル離れることを意味します。興味深いことに、これはこのフォントについて、74 ピクセルのバウンディングボックスでは、フォントが、適切にシングルスペースされたテキストの行間で、描画領域に 2 ピクセルの重なりを持つことを意味します!また、上記の測定から、このフォントでこのポイントサイズで文字列 "A" を描画すると、次の文字は開始点(キャレットとして知られる)の右 66 ピクセルに描画されるべきだとわかります。これは文字列の「論理的な」長さです。つまり、次の文字の「キャレット」つまり開始点は、20 + 66、つまり '+86+100'(ベースラインは垂直方向には変わりません)から始まるべきです。一部のアラビア語フォントは実際には右から左に描画しうるので、「キャレット」のオフセットは負になることに注意してください。これで文字 'A' のフォントメトリクスが得られますが、「キャレット」つまり開始点を基準とした、描画された 'A' の物理的な寸法はどうでしょうか。それには、2 つの色設定を入れ替えるだけです……。 |
magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
-fill black -undercolor none -annotate +20+100 'A' -trim info:
| 高さの点では、文字はその定義された描画境界内に収まっており、高さはベースラインの上 100 − 43 つまり 57 ピクセル(バウンディングボックスにぴったり)から、ベースラインの下わずか 60 − 57 つまり 3 ピクセルまでです。言い換えると、この文字にはベースラインの下の領域に描画される「ディセンダー」がありません。これから、'A' はキャレットの 3 ピクセル 前(+20 に配置されているが、最終画像は +17 にある)から、キャレット位置の 70 − 3 つまり 67 ピクセル後まで描画されることがわかります。言い換えると、このフォントは描画されると、その水平方向のバウンディングボックスよりわずかに広いのです。これは実際に描画された文字列の長さを与えますが、これはテキストを append するときに必要なキャレットのオフセット(文字列のバウンディングボックスによって定義され、その描画された長さではない)とは異なることに注意してください。言い換えると、テキストは、他の例でしてきたような実際に描画された長さのサイズではなく、それらのバウンディングボックスを使って append されるべきです。もちろん、非常に行儀の悪いフォントを使う場合は、特定の文字列がその境界をどれだけ超えて描画されるかを確認して、たとえば行末に、それ用のスペースを用意できるようにしたいかもしれません。 | フォントから抽出される寸法は、フォントの描画に使われる現在の "[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)" によっても変わります。輪郭のストロークのサイズを大きくすると、フォントの描画に必要な寸法(とバウンディングボックスのサイズ)も、より太い輪郭を収容するために同じだけ拡大されます。 |
|---|---|
| 寸法はオペレーティングシステム(種類とバージョン)や、IM がそのシステムで使っているデリゲートのフォント描画ライブラリのバージョンによっても変わります。まったく同じフォントライブラリと IM のバージョンが変わっていなくてもです。テキストの描画に異なるコンピュータが使われうる場合は注意をお勧めします。同じフォントでも結果が変わりうるからです。 | |
| --- | --- |
| 詳しくはドキュメント TrueType Fundamentals (PDF) を参照してください。これは、上記の私の一般化でさえ常に当てはまるとは限らないことを示していますが、一般的にはそうです。上記の例は寸法を整数ピクセルでしか返さないことに注意してください。フォントが使うすべての寸法は浮動小数点数です。実際、フォントが整数ピクセル(キャレット)の開始点から描画されるかどうかさえアプリケーション依存でありえ、フォントの結果の見た目に影響します。 |
複数フォントスタイルの行を作成する
複数のフォント・ポイントサイズ・スタイルを使って 1 行を作成することは、IM が本来設計されているものではありません。テキストの両端揃え、ワードラップ、画像やその他のものの周りでの折り返しのようなことまで考え始めると、さらに悪くなります。これは、ワードプロセッサ・Web ブラウザ・文書プリンタのようなプログラムが、通常はユーザーの操作のもとで非常にうまく行うたぐいのもので、プログラム制御のもとでそれをうまく行えるものはほとんどありません。これの例外のひとつが "TeX" とその仲間のプログラム群(後述の 完全なテキスト処理システム を参照)です。そのため、テキストをグラフィカルに処理することに本気なら、このプログラム群を見ることをお勧めします。もうひとつの代替案は、HTML コンバータのようなさまざまな文書の「きれいな」印刷プログラムを見ることです。これらを使って、プログラムで生成された文書をポストスクリプトに「マジック」し、それから IM がそれを、望むどんな画像形式やスタイルにでも喜んで後処理できます。"El Supremo"(IM ディスカッションフォーラムの)による(C MagickWand API インターフェースを使った)API ソリューションが、彼の FontMetrics プログラムで作られています。そして、これが 「FontMetrics」の出力例 です。
さて、IM のコマンドラインは「ワードプロセッシング」用に設計されてはいませんが、それをそうした用途に使えないという意味ではありません。ただ、より難しいだけです。ここでは、異なるフォントとスタイルでテキストを混在させる例をいくつか挙げて、人々に出発点を提供します。人々が普通に最初に思いつく最も単純な解決策は、ただ "[label:](fonts.html#label)" 画像をつなぎ合わせることです……。
magick -font LokiCola -pointsize 36 label:'LokiCola ' \
-font Candice -pointsize 24 label:'Candice ' \
-font SheerBeauty -pointsize 48 label:'SheerBeauty' \
+append wp_label_append.jpg
しかしご覧のとおり、すべての画像が画像の上端に垂直方向に揃えられており、似たフォントを使わない限り、あまり見栄えがよくありません。あるいは、append の揃えのトリックを使って、それらを下端に沿って揃えられます。
magick -size 1x50 xc:none +size \
\( -background white -font LokiCola -pointsize 36 \
label:'LokiCola ' \
-clone 0 +swap -background none -append \) \
\( -background white -font Candice -pointsize 24 \
label:'Candice ' \
-clone 0 +swap -background none -append \) \
\( -background white -font SheerBeauty -pointsize 48 \
label:'SheerBeauty' \
-clone 0 +swap -background none -append \) \
-delete 0 -gravity South -crop 0x50+0+0 +append \
-bordercolor none -border 1 -trim +repage \
-background white -flatten wp_label_bottom.jpg
ここで行ったのは、各ラベルの上部に余分なパディングを加え、水平方向につなぎ合わせる前に、それらすべてを同じ高さにクロップすることでした。その後、単純な "[-trim](https://imagemagick.org/command-line-options/#trim)" と "[-flatten](https://imagemagick.org/command-line-options/#flatten)" を使って、行の高さを最も高いラベルに設定し、背景を埋めました。ご覧のとおり、これはよりよい仕事をしますが、小さなフォントは、適切に揃えられたテキストではなく、下付き文字のような振る舞いを生み出しがちです。本当に必要なのは、すべてのテキスト文字列をその「ベースライン」で揃えることですが、それはより多くのテキスト情報にアクセスせずには非常に難しいのです。この情報はプログラム API のもとでは簡単に得られますが、コマンドラインからははるかに難しいです。ひとつの方法は前の例のセクションで示しました。しかし、ベースラインの情報を実際に集めずに、単語をそのベースラインで揃えることは可能です。"[label:](fonts.html#label)" テキスト画像は、画像のベースラインについて何の手がかりも提供しませんが、固定されたベースラインで画像を具体的に描画できます。API なしでは、描画されたテキストがどれだけ長いか高いかも直接調べられないので、まず、テキスト画像についての情報を失わないことを確実にするのに十分に大きなキャンバスを使う必要があります。それから、末尾スペースとテキストの高さを保つために、テキスト注釈で利用できる("[-undercolor](https://imagemagick.org/command-line-options/#undercolor)")機能をうまく活用し、画像トリミングのための境界を用意する必要もあります。では、コマンドラインからどうやってそれをできるか見てみましょう。
magick -size 500x100 xc:none -fill blue -draw 'line 15,0 15,99' \
-undercolor white -fill black \
\( -clone 0 -font LokiCola -pointsize 36 \
-annotate +5+60 'Loki Cola ' \) \
\( -clone 0 -font Candice -pointsize 24 \
-annotate +5+60 'Candice ' \) \
\( -clone 0 -font SheerBeauty -pointsize 48 \
-annotate +5+60 'Sheer Beauty' \) \
-delete 0 -trim +repage +append \
-transparent blue -trim +repage \
-background white -flatten wp_draw_baseline.jpg
前と同じように、画像のトリミングは 2 段階で行われます。まず、垂直な青い線を含むベース画像にテキストを描画します。こうすると、テキストをトリミングするとき、テキスト画像の幅だけがトリミングされ、すべての単語が同じベースラインの高さに残ります。それらをつなぎ合わせた後、青い構築用の線を完全に透明にすることで取り除けます。白黒の画像だけを生成しているなら、よりよい方法は、青以外のチャンネルのひとつを抽出するだけにすることで、これにより構築用の線を本当にすべて確実に取り除けます。2 回目のトリミングが上下のセクションをトリミングし、最大のバウンディングボックスに縮めます。最後に、バウンディングボックスと同じ色への flatten が、行の構築にそれが使われた証拠をすべて取り除きます。ご覧のとおり、使われたフォントやポイントサイズに関係なく、すべてのテキストが今や適切にベースラインで揃えられています。もちろん、これらの例では黒地に白のテキストしか使いませんでした。他の色も使えますが、テキストの揃えに使われる構築用の線や透明な背景と干渉しない限りにおいてです。この手法で、混在フォントのテキスト行を生成し、それらすべてを垂直方向につなぎ合わせて、より大きな文書にできるようになります。また、これらすべてを行うのは多くの作業であり、ワードプロセッサや Web ブラウザによって通常はユーザーから隠されている作業だということもわかります。こうしたことを多くやる予定なら、前に述べた代替案を調べることをお勧めします。
フォームの記入
ある標準的な記入式フォームの画像があり、よく知られた位置にあるフィールドを記入したいとします。そこで、ここに示す "[text_data.txt](../static/img/images/text_data.txt)" のようなデータファイルを用意します……。
フィールドは、テキスト幅、グラビティ(揃え方)、色、位置 x・y、そしてこのフィールドに置く実際のテキストです。さて、単純なループ式のシェルスクリプトを使って、上記で記述したとおりにテキストラベルを生成し、フォーム(背景)画像の定義されたテキスト位置に適切なテキストを割り当てられます。
cat text_data.txt |
while read width gravity color pointsize x y text
do
magick -size ${width}x -gravity $gravity -fill $color -background wheat \
-pointsize $pointsize -page +${x}+${y} label:"${text}" miff:-
done |
magick -size 200x100 xc: - -flatten text_layered.jpg
この場合の「フォーム画像」はただの空白画像ですが、本当は何でもありえます。記入される領域が見えるように、ラベルの背景色も 'wheat' に設定しましたが、通常はこれを none に設定するでしょう。上記は一時ファイルを使わず、代わりに MIFF 形式の画像のパイプラインを使っています。これは 画像ストリーミング形式 を使う一例で、個々の画像がファイルやパイプライン内で、次々に単純につなぎ合わされます。これはほんの出発点にすぎません。フォームのフィールドは何らかの定義ファイルから、記入するテキストはデータベースやその他のデータソースから来うります。使うフォント、テキストの回転など、他の属性も設定できます。幅と高さの両方を含めることもできますし、テキストをワードラップすべきなら Label ではなく Caption を使うべきです。この手法のもうひとつの例については、地図上のピン も参照してください。上記とよく似ています。
テキスト処理の代替手段
| 完全に整形されたテキストファイルや文書を生成する理想的な方法は、ImageMagick を、より大きな画像・テキスト処理システムの一部として使うことです。 ツール | 用途…… |
|---|---|
| ImageMagick | 画像のバッチ処理と準備 |
| Gimp | 一回限りの問題修正のための GUI 画像編集 |
| LyX | GUI ワードプロセッシング。次を生成するために作られた…… |
| LaTeX | 文書や書籍のためのテキスト処理…… |
| TeX | 基盤となるテキスト形式 |
| (記号やフォントをページ上に配置する) | |
| Metafont | TeX のフォントジェネレータ |
| 基本的に、ImageMagick はたくさんのことができますが、それはそれらのことに最適なツールだという意味ではありません。より大きな文書の準備には、それを、より大きな全体の一部にすぎないものとして扱ったほうがよいでしょう。上記のさまざまな 'TeX' ツールは、通常はほとんどの Linux システムの標準インストールであり、テキストと画像を統一された全体に組み合わせられます。より重要なのは、それがテキストをテキストのまま保ち、指定どおりにテキストを適切に整形し、単語とページの折り返しや、画像との配置のほぼすべての面倒な作業をしてくれることです。しかも 'doc' ファイルを無用な整形のゴミで満たすことなく。あなたが完全に制御することも、それに判断を委ねることもできます。これらは、単純なページ・ニュースレター、あるいは完全な書籍まで、あらゆる種類の文書を生成する方法を提供します。文書生成に本気なら、これらのツールは見て学ぶ価値が大いにあります。 | |
| Pango(Linux と MacOSX のみ)も代替案を提供します。これは、ImageMagick では利用できない多くのテキスト→画像処理機能を提供します。たとえば TAB、両端揃え、余白、ヘッダなどです。テキストの途中でフォントを変更できるようにする、ある種のマークアップ言語さえ持っています。 | |
| 他の解決策には、多くのテキスト→ポストスクリプト変換プログラムも含まれます。たとえば、上記の ポストスクリプトの扱い でポストスクリプトファイルの例を生成するのに示した "a2ps" などです。これは、ワードラップ・太字化・タブ制御、そしてかなり素敵なヘッダ・フッタ・枠線・複数ページのオプションとともに、多くの異なる種類のテキストファイルを変換・整形します。もちろん、これは ポストスクリプトや PDF の中間言語を介した間接的な画像処理です。もうひとつは、SVG や ImageMagick の 描画コマンド を使ってテキストをレイアウトすることですが、その場合はレイアウトを自分で扱う必要があります。テキストを画像に「マジック」するツールはたくさんあり、そのほとんどは ImageMagick と組み合わせて、テキスト画像を後処理し、自分の画像にマージできます。これにより、ImageMagick が最も得意とすること、すなわち画像処理に専念させられます。 |
![[IM Output]](../static/img/text/label.gif)
![[IM Output]](../static/img/text/label_file.gif)
![[IM Output]](../static/img/text/label_file_multiline.gif)
![[IM Output]](../static/img/text/caption.gif)
![[IM Output]](../static/img/text/caption_centered.gif)
![[IM Output]](../static/img/text/caption_height.gif)
![[IM Output]](../static/img/text/caption_height_toosmall.gif)
![[IM Output]](../static/img/text/caption_filled.gif)
![[IM Output]](../static/img/text/caption_multi_line.gif)
![[IM Output]](../static/img/text/caption_file.gif)
![[IM Output]](../static/img/text/caption_one_line.gif)
![[IM Output]](../static/img/text/caption_manual.gif)
![[IM Output]](../static/img/text/label_i8n.gif)
![[IM Output]](../static/img/text/label_utf8.gif)
![[IM Output]](../static/img/text/label_quotes.gif)
![[IM Output]](../static/img/text/label_unifun.gif)
![[IM Output]](../static/img/text/label_dingbats.gif)
![[IM Output]](../static/img/text/label_misc.gif)
![[IM Output]](../static/img/text/label_lspace_off.gif)
![[IM Output]](../static/img/text/label_lspace_5.gif)
![[IM Output]](../static/img/text/label_lspace_10.gif)
![[IM Output]](../static/img/text/label_lspace_20.gif)
![[IM Output]](../static/img/text/label_lspace-5.gif)
![[IM Output]](../static/img/text/label_lspace-10.gif)
![[IM Output]](../static/img/text/pango_span.gif)
![[IM Output]](../static/img/text/pango_test.png)
![[IM Text]](../static/img/text/page_size.txt.gif)
![[IM Output]](../static/img/text/text_trimmed.gif)
![[IM Output]](../static/img/text/text_boxed.gif)
![[IM Output]](../static/img/text/text_box_trimmed.gif)
![[IM Output]](../static/img/text/text_page.gif)
![[IM Output]](../static/img/text/ps_version_raw.gif)
![[IM Output]](../static/img/text/ps_version.gif)
![[IM Output]](../static/img/text/ps_unsharp.gif)
![[IM Output]](../static/img/text/ps_transparent.png)
![[IM Output]](../static/img/text/ps_bgnd_color.gif)
![[IM Output]](../static/img/text/ps_bgnd_tiled.gif)
![[IM Output]](../static/img/text/ps_multiply.gif)
![[IM Output]](../static/img/text/ps_overhead.png)
![[IM Output]](../static/img/text/text_draw.gif)
![[IM Output]](../static/img/text/text_options.gif)
![[IM Output]](../static/img/text/draw_mvg.gif)
![[IM Output]](../static/img/text/draw_undercolor.gif)
![[IM Output]](../static/img/text/annotate.gif)
![[IM Output]](../static/img/text/annotate_opts.gif)
![[IM Output]](../static/img/text/annotate_rotated.gif)
![[IM Output]](../static/img/text/funfont_gradients.jpg)
![[IM Output]](../static/img/text/funfont_groovy.jpg)
![[IM Output]](../static/img/text/autosize_wet.jpg)
![[IM Output]](../static/img/text/invitation_box.jpg)
![[IM Output]](../static/img/text/invitation_colored.jpg)
![[IM Output]](../static/img/text/invitation_rose.jpg)
![[IM Text]](../static/img/text/font_metrics.txt.gif)
![[IM Text]](../static/img/text/font_boxinfo.txt.gif)
![[IM Text]](../static/img/text/font_drawn.txt.gif)
![[IM Output]](../static/img/text/wp_label_append.jpg)
![[IM Output]](../static/img/text/wp_label_bottom.jpg)
![[IM Output]](../static/img/text/wp_draw_baseline.jpg)
![[IM Text]](../static/img/text/text_data.txt.gif)
![[IM Output]](../static/img/text/text_layered.jpg)