LoginSignup
1
0

More than 5 years have passed since last update.

AMP のために Rails で Carrierwave と MiniMagick を使って 画像のサイズを取得する

Posted at

はじめに

AMP対応

SEO対策のためAMP対応をしようと思ったのですが、AMPでは画像の縦横の幅を指定する必要があります。
今回はCarrierwaveとMiniMagickを使って画像をアップロードするときに画像の縦横幅も同時に保存し、
また、既存の画像のサイズも取得する処理をしたいと思います。

実装

前提

carrierwaveminimagickは既にインストールしているものとします。
また、Articleというモデルがあり、Articleがimageというカラムを持っていて、下記のようにImageUploaderを使っているとします。

app/models/article.rb
class Article < ApplicationRecord
  mount_upload :image, ImageUploader
end

画像サイズの取得

実際に画像を表示するには、

app/views/articles/show.amp.haml
%amp-img{src: @article.image, width: @article.image_width, height: @article.image_height}

のような形で表示させたいので、まずはArticleモデルにimage_widthimage_heightというカラムを追加します。
(実際に画像を保存しなくてもMiniMagickを使って画像サイズを取得することはできるのですが、画像を表示するたび、画像の枚数だけサイズを取得する処理が走るのは微妙なのでカラムを作って保存することにしました。)

$ rails g migration AddImageWidthAndImageHeightToArticles
db/migrate/20180101_add_image_width_and_image_height_to_articles.rb
class AddImageWidthAndImageHeightToArticles < ActiveRecord::Migration[5.0]
  def change
    add_column :articles, :image_width, :integer
    add_column :articles, :image_height, :integer
  end
end
rails db:migrate

画像サイズを取得し、保存するタイミングはCarrierwaveのafter storeのコールバックのタイミングにし、
save_image_sizeというメソッドを走らせるようにします。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include Carrierwave::Minimagick

  after :store, :save_image_size

  def save_image_size(file)
    image_sizes = MiniMagick::Image.open(self.url).dimensions
    self.model.update(image_width: image_sizes[0], image_height: image_sizes[1])
  end
end

これでArticleを保存し、Carrierwaveのstoreが終わったタイミングで画像のサイズが保存されるようになります。


また、既存の画像のサイズも取得し直さないといけないのでその処理も書いておくので、コンソールで走らせるなり、ファイルを作ってruby runnerで走らせるなりしてやってみてください。
処理で何らかのエラーが出たときのために、エラーが出たデータのIDを見えるようにしておく。

Article.where.not(image: nil).find_each do |article|
  if article.image_width.blank? || article.image_height.blank?
    error_article_ids = []
    begin
      image_sizes = MiniMagick::Image.open(article.image.url).dimensions
      article.update(image_width: image_sizes[0], image_height: image_sizes[1])
    rescue
      error_article_ids.push(article.id)
    end
    puts error_article_ids
  end
end

まとめ

なんというか、こんなこといちいちしなくていいようにAMPでもよきに計らって画像を表示してほしいなと切に願います。。

1
0
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
1
0