Railsでアップロードした画像のレスポンシブ表示(スマホ向けに縮小した画像表示)の実装は何が主流でしょうか?私の経験では「RMagickでスマホ向けの縮小画像を生成して表示する」くらいしかありませんでした。ですが、この方法だと複数のディスプレイサイズに細かく対応するのが大変だったり、スマホ・PCで画像を使い分けるのが面倒でした。
ここでは、Cloudinary(CDN + 画像変換サービス)を使って複数のディスプレイサイズに対応したサイズの画像を表示する方法紹介します。
ゴール
最終的に表示するHTMLとしては、imageタグにsrcsetを設定して画像を表示します。srcsetとは
Imageタグとsrcsetの例:
<img srcset="small.jpg 256w,
medium.jpg 512w,
large.jpg 1024w"
src="medium.jpg"
alt="It’s responsive!" />
実装
RailsからはCarrierWaveでCloudinaryに画像をアップロードします。
アップロードした画像はオリジナルのまま保存され、表示時にCloudinaryが画像を変換・キャッシュします。
この時に、cloudinary gem
のヘルパーで cl_image_tag
を使うことでsrcsetを設定することができます。
まずは、srcsetのブレイクポイントを設定します。
config/initializers/cloudinary.rb
# お好みで設定してください。
Cloudinary.config(srcset: {breakpoints: [576, 768, 992, 1200]})
次に view で imageタグをレンダリングします。
Hamlの例: picture
がUploaderをマウントされてものです。
= cl_image_tag picture.full_public_id, alt: '画像', fetch_format: :auto, width: 512, height: 512, crop: :pad, class: 'img-fluid'
生成されるHTMLは以下のようになります。
設定する width / height と breakpoint の組み合わせで画像サイズと解像度を最適化することができます。
<img alt="画像" class="img-fluid" srcset="https://res.cloudinary.com/hogehoge/image/upload/c_pad,f_auto,h_640,w_640/c_scale,w_576/v1576802762/ajutulersxtryuy4g9ug 576w,
https://res.cloudinary.com/hogehoge/image/upload/c_pad,f_auto,h_640,w_640/c_scale,w_768/v1576802762/ajutulersxtryuy4g9ug 768w,
https://res.cloudinary.com/hogehoge/image/upload/c_pad,f_auto,h_640,w_640/c_scale,w_992/v1576802762/ajutulersxtryuy4g9ug 992w,
https://res.cloudinary.com/hogehoge/image/upload/c_pad,f_auto,h_640,w_640/c_scale,w_1200/v1576802762/ajutulersxtryuy4g9ug 1200w"
src="https://res.cloudinary.com/hogehoge/image/upload/c_pad,f_auto,h_640,w_640/v1576802762/ajutulersxtryuy4g9ug">
Cloudinaryの画像変換についての詳細はこちら。
https://cloudinary.com/blog/responsive_images_with_srcset_sizes_and_cloudinary
使い方はどこに?
cloudinaryの公式ドキュメントやGemのREADMEを見ても srcsetの使い方はないのでもしかしたら公式な使い方ではないのかもしれません。srcsetを使うテストは存在しているので動作は問題ないように思います。
おわりに
Rails開発において、画像アップロードの保存場所はS3が人気だと思いますが個人的には、Cloudinaryを重宝しています。Cloudinaryはアップロード後にサイズやフォーマットなどの画像変換をすることができてとても便利です。ファイル数が少ないうちは無料で使えますし、Herokuだとaddonで導入するのも簡単なので、オススメです。