Nuxt.js でロゴ入りQRコードの生成ミニアプリを作ってみた

これはNuxt.js Advent Calendar 2019 12日目の記事です。

どうせアドベントカレンダー書くなら何か作ろうということで、ミニアプリを作ってみました🙌
作りたいものをただ `Nuxt.jsで作った` だけですが、速度重視にした結果、実装の都度どんなことを考えながら選択をしていったのかを追って書いています。

## URL
https://qrwi-fi.netlify.com/

## 製作期間
アイデア出しから計 5 時間ほど

## ソースコード
https://github.com/Shohei-Japan/qrwi-fi

## どんなもの？
アップロード画像を入れられる QR コードです。
こんなものを作れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230058/e62f74b7-3eb0-38fc-dc96-67f38b8456ad.png)
会社のロゴを入れてもよし、勉強会やイベントのロゴを入れていただいてもいいと思います。

アイデアの発端は、公共施設で wi-fi のパスワードを入力するのが面倒だったことがきっかけです。小文字の L と数字の 1 が見分け付かないのとかよくあって、楽にできないかなーと考えました。

そのほかで使用されるケースとしては、オフィスのゲスト用 wi-fi の案内用に印刷するとかでしょうか。 QR コードなのでどうしてもスマホオンリーになるのが悩ましいところで、残念ながら PC 使用率の多い勉強会には向いてなさそうです。

### QR コードに画像って載せれるんだっけ？
QR コードを開発した DENSO によると、画像を重ねることは推奨されておりません。
そのためこのアプリは、あくまでも個人の自己責任においてご利用ください。

>QRコードにイラストを重ねたり、デザインをのせて変形してしまうと、ちょっとした汚れや欠けでも読み取り出来なくなったり、読み取りの反応が悪くなってしまうことがありますので推奨しておりません。
規格を逸脱したQRコードについてはこの限りではございませんので、特許権を行使させていただくこともございます。
[QRコードについて (10 問目) - QRコードドットコム](https://www.qrcode.com/faq.html)

QR コードにはそれだけでコードを修復する機能を持っているそう。 (すげぇ)
誤り訂正レベルという機能がそれを担っていて、修復レベルによって QR コードの記述量が増えるようです。画像を重ねても、見えている範囲で修復ができる (できない場合もある) ということです。

>誤り訂正レベル (Error Correction Level)
QRコードに汚れなどがあっても正確に読み取れるように、読み取り不能や読み取り間違いのモジュールを修正するために付けられる誤り訂正語のデータ語に対する割合。下記の5レベルがある。
[QRコード - Wikipedia](https://ja.wikipedia.org/wiki/QR%E3%82%B3%E3%83%BC%E3%83%89)

さて、使用上の注意をよく読んだところで開発していきます。

## 要件
- ウェブ上で生成ができる。
- 入力
    - SSID、 暗号タイプ、 Key 、画像ファイル
- 出力
    - 画像ファイルとして出力できる

## 仕様技術
- Nuxt.js
- Plugin
    - QR コードの生成 (https://www.npmjs.com/package/qrcode-generator)
- Netlify

## 実装

### Nuxt.js, UI コンポーネント
Nuxt.js を採用した理由は、単純に環境構築が楽だったからです。プラグインの追加も、 Netlify へのデプロイも慣れているため無駄なことを考えずに進められます。

Nuxt.js のセットアップは特に何も特別なことはなく、空のリポジトリに create-nuxt-app で導入したのみです。
今回スタイルについてはこだわりはなかったのですが、 Vuetify を使用しています。
こだわらないなら素の CSS でもいいんじゃないかという話もありますが、それなりの UI を簡単に作れるので採用しました。

### QR コード生成
[qrcode-generator](https://github.com/kazuhikoarase/qrcode-generator) というプラグインを使用しました。

このプラグインだと出力形式が色々と選べます。他にも QR コードを生成できるものはありましたが、そもそも思いつきで始めたので要件もしっかり詰めていなかったため、後で気が変わっても気軽に切り替えられるものを選びました。

また、 QR コードとアップデート画像描画したりを重ねるために canvas を使っています。
本業のプロダクトでは [konvajs](https://github.com/konvajs/vue-konva) を使用しているため使おうと思いましたが、実装速度重視でそのまま canvas で書くことにしました。

### wi-fi の SSID, KEY の情報インプット
QR コードには文字情報をインプットすることができます。 wi-fi 情報は以下のように記述すればスマホが認識してくれるようです。

`WIFI:S:SSID文字列;T:暗号タイプ;P:暗号キー;;`

### デプロイ
Netlify で行いました。
Github のリポジトリと連携させ、 Nuxt.js のビルドコマンドを入力するだけなので、難しいこと考えずにサラッと完了です。

## 使い方
フォームにテキストを入力して、 「GET QRCODE」をクリックすれば生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230058/6f48d493-d764-b34e-65f1-b88f936006c3.png)

### フォームの説明

S, M, L とあるのは QR コードのバージョンを示しています。

>バージョンとは
>QRコードのバージョン（種類）は、1から40まで設定されており、それぞれのバージョン毎にセル構成(セル数)が決められています。
https://www.qrcode.com/about/version.html

簡単にいうと、バージョンが大きくなるたびに、QRコードに含む情報量が増えるということです。

何度か試しましたが、[公式HPにあるとおり](https://www.qrcode.com/faq.html)画像が重なることで正しく読み込めないことがありました。苦肉の策として、バージョンを変え情報量を増やす対応をしています。

理屈はともかく、まぁ何となく大きさが変わったように見えるので、 S, M, L という表現にしました。

## さいごに
再度ボタンをクリックしたときに、画像処理の順番が変わる、画像が　1 × 1 に縮小されてしまう、など粗さは目立つものの、一旦要件を満たせたかなと思います。

画像を載せても QR コードがきちんと読めるか、どの程度の大きさであればいいのかを検証するのに時間がかかってしまいました。まだ想定されていないエラーケースがありそうですが、ご容赦ください🙏🏻

スピード重視で考えると、生の HTML, CSS, JS を一つ一つ準備するより、 create-nuxt-app で構築するほうが圧倒的に早く、オーバースペックと言われようが簡単なアプリだとしても断然こっちを選んでしまいそう。

ぜひ使ってみた感想などもいただけると嬉しいです🥳

Nuxt.js アドベントカレンダー、明日の担当は rry さんです。