画像の著作権保護−その2

端末への保存は可能だが、メール添付・周辺機器(外部メモリ等)への転送を不可にする方法(PNG画像の場合)
PNG画像では、画像の著作権保護 - Kimura.Memoに書いた方法では著作権保護機能が働かない場合があります。
PNG画像の場合は、以下のようにします。

use Image::Magick;

# 除去するtEXtチャンク
# [length][type('tEXt')][data('comment'[separator]'kddi_copyright=on')][crc]
my $match = '\x00\x00\x00\x19' . 'tEXt[Cc]omment' . '\x00' . 'kddi_copyright=on' . '\x90\xCD\x99\x45';

# 入れ替え後のtEXtチャンク
# [length][type('tEXt')][data('Copyright'[separator]'kddi_copyright=on')][crc]
my $comment = "\x00\x00\x00\x1B" . "tEXtCopyright\0kddi_copyright=on" . "\x32\x16\x72\x0C";
# ↑docomoの分も一緒に入れる場合は、
#my $comment = "\x00\x00\x00\x25" . "tEXtCopyright\0kddi_copyright=on,copy=\"NO\"" . "\xD0\xC5\x26\x10";


my $image = Image::Magick->new();

$image->Read('./kddi.png');

# 後で除去するコメントを一時的に挿入
$image->Comment( 'kddi_copyright=on' );

# 一旦オブジェクトから画像データへ
my @blobs = $image->ImageToBlob();
my $buffer = join ( '', @blobs );

# 先ほど追加したコメントを正しいコメントに入れ替える
$buffer =~ s/$match/$comment/;

# オブジェクトから全ての画像を削除
@$image = ();

my $err = $image->BlobToImage($buffer);
die( $err ) if ( $err );

$image->Write('png:./kddi_c.png');

KDDIの場合、注釈拡張(Comment Extension)領域(tEXtチャンク)に、「kddi_copyright=on」という文字列を追加しろ、と公式サイトに書かれています。


そして、
金融会社の違い
や、
MODULE.JP - PNGとGIFとJPEGにコメントを埋め込む
にある通り、tEXtチャンクのキーワードとして「Copyright」を使う必要があります。


しかし、Image::MagickのComment()メソッドでは、tEXtチャンクのキーワードが「comment」に固定されているため、KCP+端末等では著作権保護機能が働かなくなってしまいます。


その為、上記のコードでは一旦キーワード「comment」でtEXtチャンクを追加し、それを正規表現で正しいキーワード「Copyright」に変更しています。
同時にチャンクのdata部の長さを示すlength、typeとdata部の値を検査するためのcrc値も変更します。


これなら、Image::Magickを使わなくても...と言うツッコミもございましょうが、

  1. tEXtチャンクの適切な挿入場所をImage::Magickが決めてくれる
  2. 画像の縮小や減色等の操作を間にはさむことができる

というメリットもあります。


このようなスクリプトを使用せず、画像編集ソフトを使って著作権保護機能を追加するには、「もじうめ」というフリーソフトが便利です。
osakana.factory - もじうめ