この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
モバイルアプリのバックエンドシステムの開発をするときに、実機での挙動を確認するため任意のURLにアクセスしたいことがあります。 今までは下記の方法で対応していました。
- ローカルHTTPサーバをたててHTMLのリンクを踏ませる
- 手入力でがんばる
HTMLのメンテナンスはだんだんと面倒になり、長いURLだと手入力するのが苦痛になってきます。 そこで、QRコードを活用してスキャンするだけでURLにアクセスできるようにしてみましょう。
前提条件
- macOS: 10.12.6
- Rust: 1.25.0 (84203cac6 2018-03-25)
- clap-rs: 2.31.2
- qrcode-rust: 0.5.0
- image: 0.17.0
ツール概要
既製のツールを使っても良いんですが、今回はRustに慣れるため自分で実装してみました。開発環境のセットアップ手順は こちらの記事 を参照してください。
ソースコードは GitHubのリポジトリ で公開しています。
処理概要
下記の流れで処理を実装します。
- 引数解析
- QRコード生成
- 結果出力
引数解析
-o
オプションで出力ファイルを指定して、引数の文字列をQRコードに埋め込む仕様とします。
解析した結果を設定する構造体を定義します。
struct GenerateOptions {
text: String,
output: Option<PathBuf>,
}
次にコマンドライン引数を解析します。
// 引数の解析ルールを定義して評価する
let matches = App::new("qr-text")
.version("0.0.1")
.author("yoshihitoh")
.about("指定した文字列のQRコードを生成します。")
.arg(
Arg::with_name("OUTPUT")
.short("o")
.long("output")
.value_name("FILE")
.takes_value(true)
.help("出力先のファイルパスを指定してください。"),
)
.arg(
Arg::with_name("TEXT")
.required(true)
.help("QRコードに埋め込む文字列を指定してください。"),
)
.get_matches();
// 引数の値とオプションを取り出す。
// TEXT: required指定なのでunwrapで取り出す。 (引数エラーの場合はここに到達しない)
let text = String::from(matches.value_of("TEXT").unwrap());
// OUTPUT: 任意指定なので、指定されている場合のみ [PathBuf]() に変換する
let output = matches.value_of("OUTPUT").map(PathBuf::from);
// 構造体に値を設定する
let generate_options = GenerateOptions { text, output };
clap-rs
を使うとコマンドライン引数を簡単に解析できます。 --help
コマンドも追加してくれるので確認してみましょう。
$ ./target/release/qr-text --help
qr-text 0.0.1
yoshihitoh
指定した文字列のQRコードを生成します。
USAGE:
qr-text [OPTIONS] <TEXT>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-o, --output <FILE> 出力先のファイルパスを指定してください。
ARGS:
<TEXT> QRコードに埋め込む文字列を指定してください。
それっぽい感じのヘルプテキストになっていますね。
QRコード生成
次に、QRコードを生成しましょう。引数解析結果の generate_options.text
をQRコードに変換します。
// QRコード生成
let code = QrCode::new(generate_options.text.as_bytes())?;
QrCode::new で生成する場合、誤り訂正機能はレベルMになります。それ以外のレベルを指定する場合、バージョンを指定する場合は QrCode::with_error_correction_level や QrCode::with_version を使用しましょう。
結果出力
最後に、QRコードをレンダリングしましょう。 GitHubのリポジトリ を確認したところ、下記のフォーマットに対応しているようです。
- ラスタ画像 (png)
- ベクタ画像 (svg)
- 文字列
今回は白黒のラスタ画像をレンダリングします。
// 画像に変換する
let image = code.render::<Luma<u8>>().build();
動作確認
動作確認のため、本ブログ記事URLのQRコードを生成してみます。
# リリース版をビルド
cargo build --release
# QRコード生成
./target/release/qr-text -o qr-code.png 'https://dev.classmethod.jp/tool/generate-qr-code-in-rust/'
生成したQRコードです。
実機のQRコードスキャナで本記事へのリンクを開けるようになりました!
おわりに
QRコードを活用してURL入力の手間を省くことができました。今後もこういった簡単なツールの実装でRustに慣れて、業務に適用できるようにしていきたいです!