Rails Ambassador

Carrierwave+Rmagicで画像リサイズ

このレッスンはCarrierwaveとRmagicを使って投稿時に画像をリサイズするTipsです。

導入・環境

既にCarrierwaveで画像アップロードができているものとします。

前回のHeroku + Cloudinary環境でCarrierwaveで画像アップロードの続きとなりますのでまだ導入されていない方は先に行っておいてください。

以下環境で動作確認しています。

ruby: 2.6.6
Rails: 6.0.3.1
Ubuntu18.04.LTS
動作確認日: 2020/05/28

Rmagicの導入

リサイズにはRmagicを使用します。

Gemfileに以下行を追加してください。

gem 'rmagick'

このままインストールを行うと、 ImageMagicのインストールがお済でない方は以下のようなエラーになります。

bundle install時のエラー
An error occurred while installing rmagick (3.1.0), and Bundler cannot continue.
Make sure that `gem install rmagick -v '3.1.0' --source 'https://rubygems.org/'` succeeds before bundling.

インストールしていない方はImageMagicをインストールしましょう。

Ubuntu(Debian系)の場合

$ sudo apt update && sudo apt install -y imagemagick libmagick++-dev

CentOs(Redhat系)の場合

$ sudo yum update && sudo yum -y install ImageMagick ImageMagick-devel
必ずOSにあったものをインストールしてください。

ImageMagicのインストールが終わったらgemをインストールします。

$ bundel install

アップローダーの編集

作成したUserUploaderを編集します。
今回はアップロード時に800px × 600pxにリサイズします。

class UserUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick #この行を追加

  # ~中略~

  #800px × 600pxにリサイズします。
  process resize_to_limit: [800, 600]

  # バージョンを作成して別のリサイズを指定し、
  # サムネイルなどを作成することも可能です。
  version :thumb do
    process resize_to_limit: [200, 150]
  end


  # ファイルがない場合のデフォルトの画像を設定できます。
  # 画像を publicに配置する場合
  def default_url(*args)
    "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  end
  # デフォルト画像を assets/images/に配置する場合
  def default_url(*args)
    ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  end
end

resize_to_fit(width, height)
縦横比を保持したまま、指定されたサイズに収まるようリサイズします。

resize_to_limit(width, height)
resize_to_fitと同様に縦横比を維持したままリサイズします。
引数の縦横サイズをオーバーした場合にのみ、指定されたサイズに収まるようリサイズします。
画像が引き延ばされて荒くなるのが嫌な方はこちらを使うと良いでしょう。

resize_to_fill(width, height, gravity = ::Magick::CenterGravity)
縦横比を維持したままリサイズし、縦横いっぱいになるように引き延ばします。
その後gravityの指定でカットします。
縦横比が違う画像を指定サイズで統一させたい時などに。

Viewの編集

サムネイルと画像を並べて表示してみます。

app/views/users/index.html.erbを編集
<%= form_with model: @user, local: :true do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  <%= f.file_field :image %>
  <%= f.submit '登録' %>
<% end %>
  
<h2>User一覧</h2>
<% @users.each do |user| %>
  <%= user.name %>
  <%= image_tag(user.image.thumb.url) %>
  <%= image_tag(user.image.to_s) %>
<% end %>

デフォルト画像を用意する

画像が登録されていない時のデフォルト画像を用意します。

publicに置く場合

  • public/images/fallback/default.png
  • public/images/fallback/thumb_default.png
を配置してください。

assets/images/に置く場合

  • app/assets/images/fallback/default.png
  • app/assets/images/fallback/thumb_default.png
を配置してください。

以上動作確認をして問題なければ完成です!