アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

nginx を使ったサムネイル画像の動的生成

こんにちは、tahara です。

画像ファイルのアップロードには Paperclip を使っています。 Paperclip は写真アップロード時にサムネイル画像を作ってくれてとても便利です。

でも、サイトのデザインが変更になって、サムネイル画像のサイズを変える必要が出た場合は、 当然のことながら全画像のリサイズ作業が必要になります。 そこで、サムネイル画像の動的生成をやってみることにしました。

要は、クックパッドさんの TOFU ですね。

nginx を使っていることもあり、簡単!リアルタイム画像変換をNginxだけで行う方法 | cloudrop をおおいに参照させていただきました(感謝です)。

次のオプションを付けて nginx をコンパイルします。

--with-http_image_filter_module

nginx の設定はこんな感じです。

location ~* /system/.*\.(jpg|jpeg|png|gif)$ {
    if ($query_string ~ .*=.*) {
      rewrite ^/system/(.*)$ /image_filter/$1 last;
    }
}

location ~* ^/image_filter/(.*)$ {
    internal;

    set $file $1;
    set $width 150;
    set $height 150;
    set $quality 75;

    if ($arg_w ~ (\d*)) {
        set $width $1;
    }
    if ($arg_h ~ (\d*)) {
        set $height $1;
    }
    if ($arg_q ~ (100|[1-9][0-9]|[1-9])) {
        set $quality $1;
    }

    if ($arg_t = "r") {
        rewrite ^ /resize last;
    }

    rewrite ^ /crop last;
}

location /resize {
    internal;
    rewrite ^ /system/$file break;
    image_filter  resize  $width $height;
    image_filter_jpeg_quality $quality;
    error_page 415 = @empty;
    expires max;
}

location /crop {
    internal;
    rewrite ^ /system/$file break;
    image_filter  crop  $width $height;
    image_filter_jpeg_quality $quality;
    error_page 415 = @empty;
    expires max;
}

location @empty {
    empty_gif;
}

Paperclip の Attachment クラスに crop と resize メソッドを追加します。

# -*- coding: utf-8 -*-
module Paperclip
  # nginx の HttpImageFilterModule で crop, resize するメソッド
  class Attachment
    def crop(width, height, quality=75)
      ret = "#{url}&w=#{width}&h=#{height}"
      if quality != 75
        ret += "&q=#{quality}"
      end
      ret
    end

    def resize(width, height, quality=75)
      crop(width, height, quality) + "&t=r"
    end
  end
end

いまだに rhtml 使っているビューで次のようにすれば OK.

<%= link_to(image_tag(facility.picture_1.crop(190, 190), alt: facility.name), facility_path(facility.id)) %>

負荷が気になりましたが、 Amazon CloudFront のおかげで全く問題ありませんでした。

これで柔軟にサムネイルサイズを変えながらデザイを行えるようになりました。

最後に、弊社では 100万組の親子を笑顔にするデザイナーを募集 しています。 まずはお気軽にお話だけでもさせてください。