Rails
QRコード
Rails5

Railsでファイル保存をせずにPNGデータとしてQRコード表示

More than 1 year has passed since last update.

概要

railsで一時的なトークンをqrコードにして表示したかった。
gemは色々情報が乗ってて簡単だったのでrqrcodeを使うことにした。

ただ一つだけ問題があり、大体どこのサイトでもqrを一旦pngで保存してurl表示って方法をとっていたり、svgで出力してたとこ。

個人的にpngの方がとりあえずサイズ調整とか簡単だしpngにしたかったが、一時トークンのためにファイル保存したり削除したりの管理コード書くのかったるいなと思ったのでファイル保存しないで直接生成したpngを表示したかった。

しかし、この記事の情報しかそのように行う情報が存在せず、ここで使われてるrmagickというgemがimagemagickのバージョンで動かなくなる(bundle install ができない。詳しくはここ)とかで、imagemagickのバージョンとかいちいち変えたりするのめんどくさかった。

で、なんか他に方法ないのかよとchunky_pngってgemのドキュメント見てたらなんか行けたのでメモ。

使うgem

rqrcode

qrコード作成gem

chunky_png

pngを扱うためのgem

gem 'rqrcode'
gem 'chunky_png'

これをgemfileに追加してbundle install

やり方

まずはrqrcodeの使いかた。
QR表示したいViewで使うためのヘルパーメソッドを作成。

require 'chunky_png'


def qrcode_tag(text, options = {})
    qr = ::RQRCode::QRCode.new(text)
 return ChunkyPNG::Image.from_datastream(qr.as_png.resize(500,500).to_datastream).to_data_url
end

一行目は引数のテキストを使ってQRコード生成
ただしこのままだとただのObjectであり、これを表示させてもQRにはならない。
svgでいいなら

return qr.as_svg().html_safe

とすればよく、これをerbファイル内で

<%= qrcode_tag request.url %>

としてヘルパーメソッド呼び出せば表示させることができる。
超簡単。
けどこれじゃあpng表示ができない。もう一手間必要。

2行目でpng表示をするためにChunkyPNGというgemを使っている。
これのChankyPng::Imageにはto_data_urlというメソッドが存在しており、これをimage_tagメソッドでerbから利用する事ができる。

まず先ほど作ったRQRCode::QRCodeオブジェクトをas_png()でpngデータにした後to_datastereamメソッドを使ってdatastreamという型にする。
ついでにサイズも調整

qr.as_png.resize(500,500).to_datastream

次にChankyPNG::Imagesのfrom_datastreamを使ってdatastream型からインスタンス生成。それのto_data_urlメソッドを実行しリターン。
全部やったのが以下

return ChunkyPNG::Image.from_datastream(qr.as_png.resize(500,500).to_datastream).to_data_url

そしてこのヘルパーメソッドをveiwファイルで呼び出すとurlが返ってくるのでimage_tagヘルパーメソッドが普通に使える。

<%= image_tag qrcode_tag "test"%>

こうすると"test"という文字列をQRコード化したimageが500,500のサイズで表示される。
screenshot.png

表示された!!!
デベロッパーツールで見てみるとソースがなぞurlになってるから裏で一時保存とかしてくれてるのかな?
まあこっちで管理したりしなくてすむからこれで問題なし!!