LoginSignup
7
5

More than 1 year has passed since last update.

【Rails】ActiveStorageで、保存する前に画像を縮小する方法

Last updated at Posted at 2022-08-31

大阪でRailsを中心に学習しているヨマ(@yoma_2003)です!
「ActiveStorageで、保存する前に画像を縮小する方法」をまとめます。

※おことわり※
断定口調でまとめますが、初学者であるため間違い等あればご指摘頂けると嬉しいです。

はじめに

やりたいこと

ActieStorageでAmazon S3等に画像を保存する場合に、指定のサイズ以下に画像を縮小してから保存したい。

必要環境

画像処理のためのツール、Gemの導入。

  • ImageMagick:画像加工ツール(本番環境ではサーバーにもインストールする)
  • Minimagick:ImageMagickをRubyから使えるようにするGem
  • ImageProcessing:画像サイズを調整するGem

結論

コントローラーに渡されたパラメーター内の画像ファイル(ActionDispatch::Http::UploadedFiletempfile)を、Imageprocessing::MiniMagickを利用して縮小処理して置き換えてからインスタンスを作成する。

モデル
Post.rb
class Post < ApplicationRecord
  has_one_attached :image
end
ビュー
new.html.erb / edit.html.erb
<%= form_with model: @post, local: true do |f| %>
  <%= f.text_field :name %>
  <%= f.file_field :image %>
  <%= f.submit "投稿する" %>
<% end %>
コントローラー
posts_controller.rb
class PostsController < ApplicationController
  # indexアクション、newアクション、editアクションは省略  

  def create
    @post = Post.new(image_resize(post_params))
    if @post_comment.save
      redirect_to root_path
    else
      render :new
    end
  end

  def update
    @post = Post.find(params[:id])
    if @post.update(image_resize(post_params))
      redirect_to root_path
    else
      render :edit
    end
  end

  private

  def post_params
    params.require(:post).permit(:name, :image)
  end

  def image_resize(params)
    if params[:image]
      params[:image].tempfile = ImageProcessing::MiniMagick.source(params[:image].tempfile).resize_to_limit(500, 500).call
    end
    params
  end
end

解説

パラメーター内の画像ファイルを縮小して置換するメソッドを定義

「パラメーターの内容自体を置換する」という処理がRailsのセオリー的にどうなのか不明ですが、アクション内の記述をほとんど変えずにそのまま代入できるので、以下の様にしました。

posts_controller.rb
  def image_resize(params)
    if params[:image]
      params[:image].tempfile = ImageProcessing::MiniMagick.source(params[:image].tempfile).resize_to_limit(500, 500).call
    end
    params
  end
画像ファイルの場所

アップロードされた画像ファイルは、パラメーター内のimageカラムで、ActionDispatch::Http::UploadedFiletempfileにバイナリファイルとして格納されている。

post_paramsで受け取ったパラメーター
pry(#<PostsController>)> post_params
=> <ActionController::Parameters {
     "name"=>"a",
     "image"=>
       #<ActionDispatch::Http::UploadedFile:0x00007faf175307c8 
         @tempfile=#<Tempfile:/var/folders/mf/abcde1234500000/T/RackMultipart20220831-21205-pnm0r4.jpg>,
         @original_filename="test.jpg",
         @content_type="image/jpeg",
         @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"test.jpg\"\r\nContent-Type: image/jpeg\r\n">
   } permitted: true>
縮小する処理

ImageProcessing::MiniMagickモジュールの機能を使用して画像ファイルを縮小する。

ImageProcessing::MiniMagick.source(params[:image].tempfile).resize_to_limit(500, 500).call

おわりに

ImageProcessing::MiniMagickモジュールでは他にも簡単に画像処理ができるメソッドがいくつか用意されているのでこの形の用途はいろいろとありそうです。

参考

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