先のエントリでImager改造云々と書いておきながらソース上げないのはどうかと思うので書きかけながら上げてみる。
序論
adiaryといえば言わずと知れた純Perl+SQL-Freeな超軽量blogwareですが*1、画像周り、特にサムネイル作成機能はImageMagickを用いているためにプラットホームを選ぶという難点があります。
そこで今回、adiary v1.44 において、ImageMagickを捨て、windowsでも動作可能なImagerを用いて編集できるようにソースの改造を試みました。
下準備
サーバー
Apacheでもよかったのですが、Windowsローカルで使うには如何せん大きすぎるので、お手軽なAnhttpdで行くことに。Anhttpdでadiaryを動かす方法については本家マニュアルを参照のこと。
ソース改変
概要
adiaryはSatsuki-systemというフレームワークの上で動いていますが、このSatsuki-systemについては現在リファレンスが整備されていません。ですので、挙動を探るにはどうしてもソースを追いかけながらデバッグするようにしなければならず、今回の修正で完全にカバーできているかどうかは必ずしも明らかではありません。
ソースコードの改変を行う場合は必ず自己責任でお願いします。
改変場所は adiary.cgi がある場所がルートとすると
- /lib/Satsuki/Upload.pm
- /info/textparser_tags.txt
の二カ所。
Uploader.pm
ファイルアップロードのコアモジュールです。コメントも書かれているのでわかりやすいかと。Imagerの書き方についてはRedirecting…を参考にしました。
これの250行目付近、
#---------------------------------------------------------------------- # ImageMagic があるとき、サムネイルを作る #----------------------------------------------------------------------
というコメント以下を次のように書き換え。
#---------------------------------------------------------------------- # ImageMagic があるとき、サムネイルを作る #---------------------------------------------------------------------- if (!$self->{make_thumbnail} || !$ROBJ->check_lib("Imager")) { return 0; } require 'Imager.pm'; # サムネイルdirの作成 $dir .= $self->{upload_thumbnail_dir}; $ROBJ->mkdir($dir); my $thumbnail_file = $ROBJ->get_filepath( $dir . $file_name ); my $image = Imager->new; $image -> read( file => $save_file_real ) or die $image->errstr; # リサイズ my $width = $image->getwidth(); my $height = $image->getheight(); my $size = $self->{thumbnail_size}; if ($size < 16) { $size=120; } if ($width<$size && $height<$size) { $size = 0; # resize しない } elsif ($width > $height) { $height = int($height*($size/$width)); $width = $size; } else { $width = int($width*($size/$height)); $height = $size; } if ($size) {# リサイズ $image = $image -> scale( xpixels => $width, ypixels => $height, ); } # ファイルに書き出し $image->write( file => $thumbnail_file) or die $image->errstr; if ($ROBJ->{File_mode}) { chmod($ROBJ->{File_mode}, $thumbnail_file); } #---------------------------------------------------------------------- # タグの再生成 #---------------------------------------------------------------------- $tag = $self->{upload_tag_thumbnail}; # 元サイズで表示 または サムネイル生成失敗 if ($form->{org_size} || !-r $thumbnail_file) { $tag = $self->{upload_tag}; # 標準画像の参照 } $tag =~ s/%(\w)/$h{$1}/g; $self->{tag} = $tag; return 0;# 成功 } 1; # おまじない
- 元のアルゴリズムからほとんど変化させてません。Image::MagickのAPIにアクセスしている部分をImagerに対応できるよう書き換えただけです。
- 気が向いたらdiff上げます。
- 元は blur がかかってますが、このソースではかけてないです。フィルタはImagerリファレンス@CPANを見つつお好きな感じでどうぞ。
- サムネイルのサイズが小さい場合は uploader.conf.cgi の <$v.thumbnail_size = 120> を適当に書き換えれば幸せになれるかもしれない。
textparser_tag.txt
230行目付近、
# 標準アップローダ
以下の
image#small = 画像アルバム, image, 3, ${public}image/$1/$2thumbnail/$3.jpg
から、末尾の .jpg を消去。
(余談だけど、この箇所を探すのに半日かかった。Namazu入れたら一発で見つかった。手動じゃ無理だ。それまでは
/lib/Satsuki/TextParser/TagPlugin/Tag_image.pm
の最後、
return "<a href=\"$link\"$tag->{class}$target><img alt=\"$name\" title=\"$name\"$size src=\"$url\"></a>";
の直前に
$url = substr($url, 0, length($url)-4);
を入れてトリムしようと考えてた。)
蛇足
先の日記
先に書いた文と前後してしまってちょっとややこしいんですが、時系列的にはこちらの記事が先。 textparser_tag.txt の修正については前の日記を参照。
ImageMagickとかGDとか
ImageMagickのPerlとの橋渡し部分(旧PerlMagick)がImageMagick本体にマージされちゃったらしく、普通にImageMagickを入れればPerlから Image::Magick を呼び出せるはずなのに何をやっても動かない。ここは本当に訳がわからなかった。
一方、GDも厄介でActivePerlのppmに存在せず、野良ppdを拾ってきたら GD/Image.al がありませんとのこと。これも使い物にならない。Imlib2はwindowsで動くのが見あたらなかった。
Acknowledgement
この素晴らしいソフトの作者である、nabe氏に心より感謝を。