19
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PhalconAdvent Calendar 2014

Day 7

Phalconを使って画像変換サーバをつくる

Posted at

個人的に2014年はPhalconと出会い、Phalconの魅力に取り憑かれ、そしてPhalconに最後まで悩まされた1年でした。そんな2014年のPhalcon Advent Calendarにこのエントリを捧げます。

Webサービスと画像変換サーバ

マルチプラットフォームを対象にしたWebサービスを展開するにあたって、必ず頭を悩ますのがデバイスごとの各種画像サイズへ対応です。固定のアイコン画像などであればPhotoshopなどで書き出すときに自動化してしまえばいいものの、ユーザから投稿された画像だったりするとサーバサイドでの自動変換が必要になったりします。

こうした問題を解決するためにCOOKPADさんのmod_tofuだったりクラスメソッドさんのRudessだったり、各社それぞれに独自の実装をしているケースが多いようです。このような機能をPhalconを使って実装してみました。

実現する機能について

変形させたい画像がpublic/imagesの中に保存されているという前提で、/image/filename.png/100というようなURLでアクセスすると縦横とも100pxのサムネイル画像を生成して表示する、ということを実現したいと思います。

事前準備

今回は実装を簡単にするためにImageMagickのcropThumbnailImage()関数を利用します。ImageMagickのライブラリが入っていない場合にはインストールしておきましょう。以下、CentOS系の場合の例です。

$ sudo yum -y install php-pecl-imagick

ルーティング設定

まず、先ほどのURLでアクセスした時に指定のコントローラを呼び出すよう、設定ファイルのルーティングをしている箇所に以下の様な内容を指定します。デフォルト設定だとapp/config/services.phpにあるはずです。マルチモジュール構成の場合などは適宜読み替えてください。

app/config/services.php
$di->set('router', function () {
    $router = new \Phalcon\Mvc\Router();
    $router->add('/image/([0-9A-Za-z\._-]+)/?([0-9]*)', [
        'controller' => 'image',
        'action'     => 'thumbnail',
        'filename'   => 1,
        'size'       => 2
    ]);
    return $router;
});

これでImageControllerのthumbnailActionが呼び出されるようになるはずです。

コントローラの実装

続いてコントローラを実装します。PhalconのImageMagickのラッパーであるImagickクラスのインスタンスに対してgetInternalImInstance()を実行するとImageMagickのオブジェクトを取得してラップされていないメソッドを直接叩くことが可能です。

app/controllers/ImageController.php
class ImageController extends \Phalcon\Mvc\Controller
{
    /**
     * 画像から指定サイズのサムネイルを作成して表示する
     *
     * @param string $filename
     * @param string $size
     */
    public function thumbnailAction($filename, $size)
    {
        $img = new \Phalcon\Image\Adapter\Imagick("images/$filename");

        $imagick = $img->getInternalImInstance();
        $imagick->cropThumbnailImage($size, $size);

        $response = new \Phalcon\Http\Response();
        $response->setContentType($img->getMime());
        $response->setContent($img->getImage());
        $response->send();

        $imagick->destroy();
        exit();
    }
}

これだけで指定した画像を任意のサイズに変形して出力することが可能です。ちなみに縦横比が正方形ではない場合、画像の中央から正方形になるように切り出したものが変形されます。(横長の場合、左右の両脇は同じ幅でトリミングされます。)

最後に

私が現在エンジニアとして働いているアオイゼミではサーバサイドの実装にPhalconを使っています。この記事にまとめた仕組みも活用しており、実際の利用にあたっては、クライアントアプリの負担を軽くしたり、多くのリクエストを効率的に捌けるよう、以下の機能を組み込んだ実装になっています。

  • 画像によっては正方形ではなく縦横とも任意のサイズに変形可能
  • リクエストURLをキーに変形後の画像バイナリをキャッシュして、一度生成した画像は再利用
  • URLにオプションを付与することでサムネイルを円形にクロップ
  • 幅と色を指定して、生成したサムネイルに任意の枠線を動的に合成
  • 可用性向上のため画像ファイルの実体はAWSのS3に保存して、そこから取り出す

Phalconを使って自社サービスを開発したいエンジニアを絶賛募集中ですので、ご興味ありましたらぜひご連絡ください!

19
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?