MTの画像表示(Sample文字を入れる)

画像の表示はMovable Typeの4.xぐらいから<mt:Assets></mt:Assets>というブロックタグでアップロードした画像やドキュメントを表示できるようになりました。これらを使うと結構複雑な画像管理ができます。
 ここではいろんなスクリプトを使ってMovable Typeでアップロードした画像に自動的に「Sample」という文字を入れ、更にサムネイルにはSample文字を入れない...というスクリプトの説明をします。著作権や製作者の意図によっては画像などは(インターネット中に流布しているからといって)無償で何でもかんでも使えるというわけではないので、それらの行為を少なからずブロックするという意味でSample文字を入れます。

必要な環境
  • ImageMagickが使える
  • phpでimagickが使える
  • Movable Typeが使える
Movable Typeを利用している環境では必然的にImageMagickが利用可能になっていないといけない筈なので、ここではphpでimagickが使えるようになっている環境がポイントです。
(しかし、紛らわしいですね。ImageMagickとimagick...間違ってしまいますよ。)

 これらの機能を実現するには多少Movable Typeのファイル管理の順序を知っておく必要があります。一つ目はMovable Typeではサムネイルを自動的に作成してくれるのですが、そのサムネイルの作成はアップロードした元々の画像の原本からサムネイルを作成します。ですから、順序としてその原本になる画像にSample文字を入れたら、Sample文字の入ったサムネイルが作成されてしまうのでサムネイルが恰好悪くなってしまいます。サムネイルにSample文字を入れないためにはMovable Typeの機能とは別に独自のスクリプトで独自のディレクトリ内にサムネイルを生成しておく必要があります。

<mt:Assets type="image">
<?
$thumb = new Imagick("<$mt:AssetFilePath$>");
$thumb->resizeImage(150, 0, imagick::FILTER_MITCHELL, 1);
$thumb->writeImage("thumbnail/<$mt:AssetFileName$>");
?>
</mt:Assets>

 スクリプト自体は非常に簡単です。phpのimagickにはあらかじめ膨大なメソッドが用意されているのでそれを使うだけです。ここではオブジェクトの作成(new Imagick)、リサイズ(resizeImage)と書き出し(writeImage)の3つのメソッドしか使っていません。何やら非常に面倒なのがMTタグとphpが混在し、更にphpではあまりお馴染みではないオブジェクトを使っているのでちょっと不慣れな人には何やら難しいものに見えるかもしれません。しかし単にサムネイルを作るにはこれで十分です。
 まず、<mt:Assets>でアイテム(画像)を読み込みます。アイテム関連のMTタグはたくさんありますが、ごく頻繁に使うのは、

<$mt:AssetFileName$>
<$mt:AssetFilePath$>
<$mt:AssetURL$>

 これぐらいでしょうか。<$mt:AssetThumbnailURL$>とかいうサムネイルを表示する便利なものもあるのですが、最近の高スペック&光回線みたいな環境下では<img src="<$mt:AssetURL$> height="100" />みたいな感じで十分かもしれないし、また今回説明するようにサムネイルを作ってしまってそれを表示すればいいわけです。
 MTタグにはパスを内包するものとして、内部の作業に必要なディレクトリパス(/home/username/public_html/blog...)みたいなパスと外部接続に使うURLパス(http://www.laughlang.net/blog...)のようなパスと単にファイル名などを単体で表示する(file_002.jpg)みたいなものと大きくわけて3種類あります。(もちろんなんちゃらのタイトルとか、なんちゃらのタグとかいろいろありますが...直接パスにはあまり関係がありません。)


Sampl

<mt:If tag="AssetCount">
<mt:Assets lastn="1">
<?
//ファイルのパス設定
$sitepath = "<$mt:BlogSitePath$>"; //サイトのパス(/home/user...)
$siteURL = "<$mt:BlogURL$>"; //サイトのURL(http://...)
$thumbnail_dir = "thumnail"; //サムネイルの書き出しディレクトリ(パーミッション777で自分で作成
$assetfilename = "<$mt:AssetFileName$>"; //FileName単体(002.jp)
$assetfilepath = "<$mt:AssetFilePath$>"; //Fileのパス(/home/user/...002.jpg)
$thumbnail_filepath = "<$mt:BlogSitePath$>"."$thumbnail_dir"."/$assetfilename"; //作成したサムネイルのパス(/home/user...)

$thumbnail_size = "300";
$sample = "<$mt:blogsitepath$>template_item/sample/sample.png";
/*
print "$sitepath<br />";
print "$siteURL<br />";
print "$thumbnail_dir<br />";
print "$assetfilename<br />";
print "$assetfilepath<br />";
print "$thumbnail_filepath<br />";
*/

//$item_relative_path = "./$thumbnail_dir/$assetfilename";
if (file_exists($assetfilepath)) {//アイテムが存在するかどうか
   //print "アイテムが存在。<br />";

   if (!file_exists("thumbnail/<$mt:AssetFileName$>")) {//サムネイルがない場合は作成
      //----------------------------------------
      //Sample文字の入っていないサムネイル画像作成
      //----------------------------------------
      //リサイズ
      $thumb = new Imagick("<$mt:AssetFilePath$>");
      /* 2008/11/25追記 比率を保ってリサイズするには、基準となる軸以外に0を指定する
      (誤)$im->resizeImage(100, 100, imagick::FILTER_MITCHELL, 1);
      */
      $thumb->resizeImage($thumbnail_size, 0, imagick::FILTER_MITCHELL, 1);
      $thumb->writeImage("thumbnail/<$mt:AssetFileName$>");

      //----------------------------------------
      //アイテム(元画像)にSampleの文字を埋め込み
      //----------------------------------------
      $image = new Imagick("<$mt:AssetFilePath$>");//Sampleを重ねる元画像
      $image_over = new Imagick($sample);//Sampleの文字画像

      $base_image = new Imagick();//ベース画像を作成

      //元画像の大きさを取得(ベース画像の大きさを調整::元画像と同じ大きさにする)
      $width = $image->getImageWidth();
      $height = $image->getImageHeight();
      //ベース画像を元画像の大きさで作成(幅、高さ、背景色)
      $base_image->newImage($width, $height, new ImagickPixel("black"));
      $base_image->setImageFormat("jpg");//合成後の画像のフォーマット

      //画像の合成(重ね合わせ)数値はx,y posを表す
      $base_image->compositeImage($image, imagick::COMPOSITE_OVER, 0, 0);//元画像の位置(背景や枠線が不必要な場合は、0,0)
      $base_image->compositeImage($image_over, imagick::COMPOSITE_OVER, 50, ($height/2));//Sample文字の位置

      //合成画像を書き出し
      $re = $base_image->writeImages("<$mt:AssetFilePath$>", true);
      $base_image->destroy();

      //print "サムネイルがないので作り、元画像にSampleの文字をいれました。<br />";
      //print "<img src='<$mt:AssetURL$>' />";

   } else {
      //print "サムネイルがあるので何もしません。";
      //print "<img src='<$mt:AssetURL$>' />";
   }
} else {
   //print "アイテムが不在。<br />";
}

print "<div id='top_image'>";
print "<a href='<$mt:AssetURL$>' target='_blank'>";
print "<img src='./thumbnail/<$mt:AssetFileName$>' class='asset-img-thumb' />";
print "</a>";
print "</div>";

?>
</mt:Assets>
<mt:Else>
<?
//アイテムがない場合は、サムネイルを削除
$open_dir = "thumbnail";
if ($dh = opendir($open_dir)) {
  while (($file = readdir($dh)) !== false) {
    if(!is_dir($file)){
       $unlink_path = $open_dir."/".$file;
       unlink($unlink_path);
       //print "$file<br />\n";
    } else {
       continue;
    }
  }
  closedir($dh);
}
?>
</mt:Else>
</mt:If>