Perl モジュール Image::Magick を使って CGI プログラムでアップロードした画像に透かし(ウォーターマーク)を付ける方法のご紹介です。
むやみな転用を防ぐための「サンプル」などの表示を画像の上に表示します。
これはシリーズ記事「Image::Magick の使い方」の 8/8 番目です。 目次を表示
Image::Magick で画像に透かしを付ける
Image::Magick で画像に透かしを付ける手順
文字なども透かしにできます。手順は少し複雑で、以下の通りです。
- 透かしにする内容(文字やマーク)を白黒画像として描く
- 透かし部分だけを薄く有効にするマスクを作成
- マークファイルとマスクと元画像を結合
もし透かしにアイコンなどの画像を使用したい場合はマークファイルとマスクファイルは手動で作成しサーバにアップロードしておき、Image::Magick で読み込みと結合を行います。
Image::Magick サンプルコード:Image::Magick で画像に透かしを付ける
my $watermarked;
eval{
#元画像と同じサイズの画像を作る
$watermark=$img->Clone();
$ret = $watermark->Set(
colorspace => ‘RGB’,
);
#一旦黒で塗りつぶし
$ret = $watermark->Colorize(fill=>’Black’);
#マスク画像用に複製しておく
my $mask = $watermark->Clone();
#白字で透かしの内容を書く
$ret = $watermark->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf’,
pointsize=>45, fill=>’white’,
text=> ‘SAMPLE’,
rotate=>-30,
gravity => ‘NorthWest’,
geometry => ‘+30+100’, #gravity指定した位置からのパッディング
);
この時、$watermark->Write で書き出すと以下のような状態です。黒字に白で字を書いたところです。
$ret = $watermark->Shade(geometry=>’135×45′);
#Shadeのパラメータ:(光源の位置)x(光源と地面の角度)
#光源の位置は0が真東(右)、90は北(上)。135は北西(左上)から光が当たっている状態
この時、$watermark->Write で書き出すと以下のような状態です。Shade の効果で文字が立体的になっています。
#この例では文字の部分だけ透過させたいので、
#上で描いた文字と同じ位置に縁を付け加えて薄いグレーで色を付けている。
$ret = $mask->Annotate(
font=>’/path/to/font/sazanami-gothic.ttf’,
pointsize=>45, fill=>’gray20′,
strokewidth=>1, stroke=>’gray20′,
text=> ‘SAMPLE’,
rotate=>-30,
gravity => ‘NorthWest’,
geometry => ‘+30+100’, #gravity指定した位置からのパッディング
);
このマスクだけを、$mask->Write で書き出すと以下のような状態です。黒い所は後で写真を透過し、白い所は透かしとなる文字模様を反映させます。この状態だと、この文字の薄さで、先ほどの影付きの「SAMPLE」を透過する、という事になります。
$watermarked=$img->Clone();
$ret = $watermarked->Composite(
image=>$watermark, #マークを指定
gravity=>’NorthWest’,
geometry=>’+0-30′,
mask=>$mask, #マスクを指定
);
};
if ($ret||$@) {
print “マスク画像の作成に失敗しました。: $ret $@”;
exit;
}
$saved{wartermark} = “$dir/watermark.png”;
$saved{wartermarked} = “$dir/watermarked.png”;
my $ret;
eval{$ret=$watermark->Write(filename=>$saved{wartermark})};
if ($ret||$@){
print “透かしファイルの保存に失敗しました。: $ret $@\n”;
exit;
}
eval{$ret=$watermarked->Write(filename=>$saved{wartermarked})};
if ($ret||$@){
print “透かし付きファイルの保存に失敗しました。: $ret $@\n”;
exit;
}
これで透かし付きファイルの保存ができました。
そして最後にこれがちょっと不思議なのですが、メッソッド Composite は $watermarked->Composite と、写真に適用したのに、$watermark (マークファイル)の方も、このメソッド実行の後 $watermark->Write で書き出してみると、こちらにもマスクが適用されています。そういうもののようです。