LoginSignup
25
25

More than 5 years have passed since last update.

Heroku + Railsな環境で、Dragonflyを使って画像を動的にリサイズする (with Amazon S3/CloudFront)

Last updated at Posted at 2014-03-15

最近「Annict」という、見たアニメを記録して、各サブタイトルの感想をTwitterやFacebookにシェアできるサービスをリリースしました。そのサービスの画像表示部分に「Dragonfly」を使用したので、その設定内容をまとめてみました。

環境

  • Heroku
  • Amazon S3
  • Amazon CloudFront
  • Rails 4.0.4
  • Dragonfly 1.0.3
  • Dragonfly::S3DataStore 1.0.3

手順

インストール

まずは「Dragonfly::S3DataStore」というgemを使って、Amazon S3に画像をアップロードできるようにします。

gem 'dragonfly-s3_data_store'

設定ファイルを用意します。

config/initializers/dragonfly.rb
require 'dragonfly'
require 'dragonfly/s3_data_store'

# Configure
Dragonfly.app.configure do
  plugin :imagemagick

  protect_from_dos_attacks true
  secret '201403152307...'

  url_format "/media/:job/:name"

  datastore :s3,
    bucket_name:       ENV['S3_BUCKET_NAME'],
    access_key_id:     ENV['S3_ACCESS_KEY_ID'],
    secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
    region:            ENV['S3_REGION']

end

# Logger
Dragonfly.logger = Rails.logger

# Mount as middleware
Rails.application.middleware.use Dragonfly::Middleware

# Add model functionality
if defined?(ActiveRecord::Base)
  ActiveRecord::Base.extend Dragonfly::Model
  ActiveRecord::Base.extend Dragonfly::Model::Validations
end

画像アップロードの準備

画像情報を管理するモデルにDragonflyの設定を追記します。ここでは Item モデルに image という名前で設定します。

app/models/item.rb
class Item < ActiveRecord::Base
  dragonfly_accessor :image
end

items テーブルにカラム image_uid を追加します。画像をアップロードすると、このカラムに画像までのパスが格納されます。

class AddImageUidToItems < ActiveRecord::Migration
  def change
    add_column :items, :image_uid, :string
  end
end

これで以下のようなフォームから画像がAmazon S3にアップロードできるようになります。

<% form_for @item do |f| %>
  ...
  <%= f.file_field :image %>
  ...
<% end %>

画像を表示する

画像は以下のようなコードで表示することができます。

<%= image_tag @item.image.thumb('300x300').url, size: '300x300' %>

アップロードした画像が 300x300 でなくても、Dragonflyが 300x300 のサイズに動的にリサイズして返してくれます。便利。

Amazon CloudFrontを利用する

上のコードで画像を表示したときの画像のURLは http://www.annict.com/media/(長いユニークな文字列)?sha=(ハッシュ値) となります。このURLにアクセスすると、その度に画像のリサイズ処理が発生するため、表示がとても重くなります。そこでCloudFrontを間に挟み、リサイズ後の画像をキャッシュするようにします。

CloudFrontの設定

Distributionを一つ作成し、以下のように設定します。

設定項目 設定値
Origin Domain Name www.annict.com
Forward Query Strings Yes

他の設定項目についてはお好みで良いですが、画像URLに ?sha=(ハッシュ値) が付くため、 Forward Query Strings については Yes と設定する必要があります。(初めてCloudFrontの設定をしたとき、デフォルト値の No にしたままにしていて、画像がキャッシュされず少しハマりました…)

最後に、作成したCloudFrontのURLをDragonflyの設定ファイルに追記します。

config/initializers/dragonfly.rb
# ...

Dragonfly.app.configure do
  # ...

  url_host 'http://hogehoge.cloudfront.net'

  # ...

これで画像のURLが http://hogehoge.cloudfront.net/media/(長いユニークな文字列)?sha=(ハッシュ値) となり、最初のリサイズ以降はCloudFrontからリサイズ済みの画像が返るようになります。

設定完了

以上が「Annict」で利用しているDragonflyの設定になります。内部ではImageMagickを使用しているので、リサイズだけでなく、変形や、blurなどの処理を動的にかけることもできます。例えばAnnictのプロフィールページの背景画像には、動的にblurをかけています。

とてもお手軽にできるので、是非お試しください。現場からは以上です。

25
25
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
25
25