Image::Magick で画像に文字を書く方法


Perl モジュール Image::Magick を使って CGI プログラムでアップロードした画像に文字を書く方法の紹介です。著作権表示(コピーライト)や画像の説明を画像の上に直接書き込む時に利用できます。日本語でもOKです。

画像にCSSでテキストをかぶせる方法を探している方はこちらもどうぞ。
「すぐ使えるCGI 文字付きホームページスライドショーの作成」

これはシリーズ記事「Image::Magick の使い方」の 7/8 番目です。 目次を表示

Image::Magick で画像に文字を書く

Image::Magickの使い方サンプルコード元画像

元画像

Image::Magickでコピーライト表示を書き込んだ画像

コピーライト表示を書き込んだ画像

画像に文字を書く際の処理のポイント

フォントの準備

日本語を画像に書き込むためにはCGI を実行するサーバ内に日本語フォントがインストールされている事が必要です。

写真の上でも見やすい影付き文字の出力方法

写真などに文字を重ねる場合、文字が埋もれてしまわないように少しずらした位置に文字色と違う色で同じ文字を書いておきます。このページのサンプルでは茶色の上に白字を重ねています。
ずらす以外にも、下になる文字には縁を付けて縁取りがあるように見せるなどの対応もあります。

Image::Magick の色指定方法

色の指定はWebカラーや色名で行えます。下記ページを参照して下さい。
http://www.imagemagick.org/script/color.php

Image::Magick サンプルコード:画像に文字を書く

#文字列設定
my $annotate_str = ‘(c)ミヤビッチの穴’;

my $annotate;
eval{
$annotate = $img->Clone();
$ret = $annotate->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf‘,
pointsize=>16, fill=>’maroon‘,
text=> $annotate_str,
gravity => ‘SouthEast’,
geometry => ‘+10+10‘, #gravity指定した位置からのパッディング
);

文字を書くメソッドは Annotate です。上の例ではまず「maroon」(茶色)で下に敷く文字を書いています。

位置の指定は「gravity」と「geometry」で行い、「gravity」は画像のどの辺りに文字を配置するかを決定します。ここで指定している「SouthEast」は「南西」の意味で、地図の表示と同じく、右下の方に文字を配置します。(開発者と同じ、北半球の住人で幸運です!)

「geometry」は CSS での padding に相当し、「+AA+BB」と指定すると「AA」は横方向の余白の設定、「BB」は縦方向の余白の設定になります。

$ret = $annotate->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf’,
pointsize=>16, fill=>’white‘,
text=> $annotate_str,
gravity => ‘SouthEast’,
geometry => ‘+11+11‘, #gravity指定した位置からのパッディング
);
};

次に、メインになる白字の出力です。
色と位置(geometry)を少しだけ変えて同じ内容を出力します。「gravity」が「SouthEast」(右下基準)ですので、「geometry」を縦横 1 ずつ増加させた場合、少しだけ左上に寄る事になります。

if ($ret||$@) {
print “文字の書き出しに失敗しました。: $ret $@”;
exit;
}
$saved{annotated} = “$dir/annotated$ext”;
eval{$ret = $annotate->Write($saved{annotated})};
if ($ret||$@){
print “文字書き出し後のファイルの保存に失敗しました。: $ret $@\n”;
exit;
}

文字の下地のバリエーション

縁取りをする

上記例のように下地の文字をずらすのではなく、全体に枠を付けて表示する事もできます。

文字の縁取りを設定して画像に文字を書く

縁取り付きの文字を書く

$annotate_bgbk = $img->Clone();
$ret = $annotate_bgbk->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf’,
pointsize=>16, fill=>’gray20‘,
strokewidth=>1, stroke=>’gray20‘,
undercolor=> ‘red’,
text=> $annotate_str,
gravity => ‘SouthEast’,
geometry => ‘+10+10′, #gravity指定した位置からのパッディング
);
$ret = $annotate_bgbk->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf’,
pointsize=>16, fill=>’white’,
text=> $annotate_str,
gravity => ‘SouthEast’,
geometry => ‘+10+10‘, #gravity指定した位置からのパッディング
);

下地を縁取りタイプにする場合は、下地の文字に縁取りを付けておきます。strokewidth で幅を、stroke で色を指定します。その上で、メインの文字は geometry を変えずに書き出します。
なお、始めから fill => ‘white’, stroke => ‘gray20’ とやってしまうと、文字がくっきりと出ません。

位置指定のバリエーション

上記例のように「gravity」を「SouthEast」と指定した場合は「geometry」は画像の右下から文字の右端(終了点)までの余白を表します。一方「gravity」を「NorthWest」とした場合は左上が起点となり、同じ「geometry」の指定が画像の左上から文字の左端(開始点)までの距離を指定するものになります。つまり、左余白がAA、上余白がBBです。この辺りは CSS の position 指定の right、left や背景画像の指定方法などと同じイメージです。

実際に書き出される文字下記のようになります。

gravity => NorthWest

gravity => ‘NorthWest’,
geometry => ‘+10+10’,
NorthWest(左上)を起点にして文字の位置指定

gravity が NorthWest(左上)の時

gravity => SouthEast

gravity => ‘SouthEast’,
geometry => ‘+10+10’,
gravity が SouthEast(右下)の時の位置取り

gravity が SouthEast(右下)の時

位置指定の微妙な違いについて

ところで、geometry を「+10+10」と縦横同じだけ指定しているのに、下余白と右余白には微妙な違いがありますよね。下余白の方が大きく見えます。gravity が SouthEast の時の下余白と gravity が NorthWest の時の上余白も微妙に違います。

これは、フォント自体が行間や字間をある程度抱えているせいで、背景色を付けて見てみると余白は同じ量だけ設定されている事が分かります。行間や字間はフォントによって異なるため、開発時は試行錯誤しながら値を決定する必要があります。

SouthWest で背景色を付けた文字位置指定

SouthWest での文字位置

NorthWest で背景色を付けた文字位置指定

NorthWest での文字位置