ぷららのblogサービス「Broach」のあまりの重さと対応の遅さに業を煮やし、工房blogを移設した訳ですが、0xF9D1
他社のblogサービスにそのまま乗り換えても面白くないので、webサーバにblogソフトウエアをインストールして、自前で調達することにしました。(さしずめ、blogの自炊?)
インストールしたblogソフトウェアは、「Movable Type 5」(以下、MT5)という、現在最も広く普及しているもののひとつを選定しました。
#MT5のインストールから実際に公開できるようになるまでには、いろいろと苦難の道がありましたが、これについては、また別の機会に述べることにします。
このエントリでは、標記、「MT5でサムネイルをランダムに表示する」方法について、自分への備忘録も含めてまとめることにします。
工房blogには、すでに1,000件近いエントリと、数1,000枚におよぶ大量の画像がアップされています。
これらの画像について、フォトギャラリー的に過去の画像を表示し、その画像を含むエントリにリンクを張っておけば、過去のエントリに対するアクセスを期待することができます。
これまで、MT5に標準で設定されているWidgetの「アイテム」を改造して、サムネイルを表示するようにしていました。
ただ、標準の状態では、「直近のものから(連続的に)10枚を選ぶ」など、機能がかなり限定されています。
これを補うため、「ランダムにアイテムを抽出する」というプラグインが公開されていますが、ここでいう"ランダム"のタイミングとは、「エントリを作成するなど、blogが再構成された場合に」という条件付きです。
これを補うため、「コメントやトラックバックの追加などをトリガとして、blogを再構成する」方法や、「cronを使って、毎日定期的にblogを再構成する」方法などが紹介されています。
ただ、いずれの方法でも、blogを再構成しなければならないため、「訪問者がページにアクセスする度に、ランダムにアイテムを表示する」という機能は実現することができません。
ネット上をいろいろ探してみましたが、ここまで凝った機能を実現する方法は紹介されていないようです。(探し方が足りないのかも知れませんが)
そこで、
「足らぬなら 作ってしまえ プラグイン」0xF9C3
ということで、所望の機能を自前で実現することにします。(プラグインの自炊)
- 訪問者がページにアクセスする度に、過去のサムネイルをランダムに抽出し、表示する。
- MT5のDatabaseサーバ(SQLサーバ)にアクセスし、過去のアイテム(サムネイル)の一覧を得る。
- サムネイルの一覧の中から、重複がないよう、所定の個数分、ランダムにサムネイルを抽出する。
- サムネイルへのリンクと、サムネイルを含むエントリへのリンクを返す。
さっそく、PHPとSQLのスクリプトをゴリゴリ書いて、MT5のテンプレートを改造しましたが、以下のような問題点があることが分かりました。
- ページを表示する度に、Databaseサーバにアクセスするため、サーバに負荷が掛かる。(ページの表示が遅い)
- サムネイルを所定の大きさにリサイズする際、ブラウザの縮小表示に任せると、サムネイルの画質が悪くなる。(ジャギーが発生する)
MT5では、画像をアップロードした際、自動的にサムネイルを作成し、サーバに格納してくれますが、このサムネイルの横幅は、75/100/240pixelなどの特定の値となっており、そのままフォトギャラリー用の画像として使うには、適さないようなサイズです。
また、一度画像をアップロードし、サムネイルが作成されてしまうと、その後リサイズをしようにも、二度と作成されることはありません。
ということで、標記、「MT5でサムネイルをランダムに表示する」方法の第一段階として、以下の機能を実現します。
- Databaseサーバに負荷を掛けないよう、予めサムネイルのリストを作成し、blogサーバに格納しておくておく。
(サムネイルのリストは、画像が新たに追加された時のみ更新する) - サムネイルは、フォトギャラリーのデザインに合わせて、後からでも任意の大きさにリサイズできるようにする。
- リサイズの際には、原画像を再サンプリングし、ジャギーのない滑らかな画像となるようにする。
- 原画像の更新状況をチェックし、更新されていた場合には、自動的にサムネイルを再作成するようにする。
(=後から画像を差し替えても、それに合わせてサムネイルを自動生成する)
(=一度生成したサムネイルは、必要のない限り再生成せず、blogサーバに掛かる負荷を軽減する)
後からでも自動的にサムネイルを再生成するようにしたのは、工房blogでは、後から画像を差し替えることが、ままあるからです。
(こだわりの内容のエントリは、後からびみょ~にバージョンアップしてたりします)
能書きはこれくらいにして、いよいよPHPのスクリプト(thumbnail.php)です。
- サムネイルのリスト(thumbnail.dat)を読み込み、配列($ThumbnailImageArray)に格納する。
- Databaseサーバから、登録されているアイテム(画像)のリストを読み込み、配列($AssetImageArray)に格納する。
- サムネイルのリストとアイテム(画像)のリストとを比較し、新たに登録されたアイテム(画像)の有無を検出する。
- 新たに登録されたアイテム(画像)があった場合には、所定の大きさのサムネイルを生成し、保存する。
- サムネイルのリストに、新たに生成したサムネイルを追加し、保存する。
実行した結果(サンプル)です。サンプルでは、原画像から80x60pixelのサムネイルを作成しています。
左側の画像は、原画像を、ブラウザの縮小機能を用いて表示したものです。
ブラウザのバーションにも依りますが、「ニアレストネイバー法」(Nearest Neighbor Method)を用いて縮小している場合には、画像のサンプリングが荒くなるので、ジャギーが発生します。
一方、右側の画像は、原画像を、PHPの画像処理ライブラリ(GD)を用いて縮小したものです。
「バイキュービック法」(Bicubic Method)を用いているので、画像の滑らかさが改善されています。
また、原画像がサムネイルのアスペクト比より大きい場合(画像が横長の場合)には、サムネイルのアスペクト比に合うように、横方向にセンタリングしてからトリミングしています。(2段目の画像)
同様に、原画像がサムネイルのアスペクト比より小さい場合(画像が縦長の場合)には、縦方向にセンタリングしてからトリミングしています。(3段目の画像)
#ここまで細かい芸当は、MT5に標準のものではできません。
なお、PHPには、以下の2つのオプションを設けてあります。
http://www.(userdomain)/blog/thumbnail.php?force=1
「Force」オプション ・・・ このオプションを設定すると、画像がサムネイルのリストに登録されているか否かに関わらず、強制的にサムネイルを再作成します。
http://www.(userdomain)/blog/thumbnail.php?silent=1
「Silent」オプション ・・・ このオプションを設定すると、画面に実行中のメッセージやリサイズの実行結果を出力しません。cronを使って毎日定期的に実行する際などに、不要なゴミ(cronの実行結果logなど)を出さずに済みます。
ということで、これでサムネイルをランダムに表示するための素材が揃いました。0xF9C6