Swift Playgroundsで学ぶiOSプログラミング 第64回
低レベルのカメラ機能を使ってQRコードをスキャン
QRコードの内容を読み取るプログラム
2017年12月04日 17時00分更新
前回は、ジェネレーターカテゴリーのCore Imageのフィルターを使って、入力した文字列をQRコード(2次元バーコード)の画像に変換するプログラムを作りました。しかし、そのままでは、生成したQRコードが正しいのか確認する術がありません。そこで今回は、QRコードの内容を読み取るプログラムを作成します。
そのためには、もちろんiPadの内蔵カメラを使います。もし、Core ImageにQRコードの画像を入力としてその内容を出力するという、前回使ったものと逆の機能があれば楽なのですが、残念ながらそのようなフィルターはありません。もちろん撮影した写真のピクセルの値(画像の濃淡)を1つずつ調べて、QRコードをデコードするプログラムをゼロから書くことも不可能ではありませんが、画像解析の技術が必要となりプログラムもかなり大規模なものとなってしまいます。
しかしiOSのAVFoundationには、カメラを使って撮影しながらその中に含まれるバーコードやQRコードをスキャンして内容を読み取る機能が備わっています。Core Imageと一緒に使ったImage Pickerより、ずっと低レベル(ハードウェアに近い)の機能です。撮影時のUIやファインダー機能も含んでいないので、すべて自前で用意してやる必要があります。とはいえ、その部分は大した手間ではありません。さっそくプログラムを書いていきましょう。
AVキャプチャー機能を利用
撮影機能としては、AVFoundationのAVCaptureSessionというクラスを使います。これは、その名のとおり一種のキャプチャ機能ですが、かなりフレキシブルにできています。このオブジェクトには入力と出力を設定します。それらの設定次第で単なるカメラとしてだけでなく、さまざまな用途に対応するのです。
今回は、入力にiPadのリアカメラを指定します。出力として、静止画を設定すれば写真撮影もできますし、動画を設定すればビデオ撮影も可能です。ただし今回はそのどちらでもなく、メタデータを出力に指定します。メタデータとは今回の場合、認識して読み取ったQRコードということになります。そのメタデータから、内容を表す文字列も取り出すことができます。
今回のプログラムの大まかな流れは、まずAVCaptureSessionのオブジェクトを作成し、そこに入力と出力を設定してから、セッションを起動し、デコード可能なパターンが視野に入ったら、自動的にデコードして結果を表示する――といったものになります。実際には撮影中の画像(映像)を表示しないと、ユーザーがどこを狙ってカメラの視野を決めればいいかわかりません。そこで、プレビュー用のレイヤーというものも用意してイメージビュー(UIImageView)に表示します。
すでに述べたように、AVFoundationはかなり低レベルな部分をカバーするものなので、今回のプログラムも、細かな設定が多くなっています。それらの解説は省きますが、上で説明した流れを理解していれば、自然に意味もわかってくるでしょう。
プログラムの先頭部分では、いつものUIKitとPlaygroundSupportに加えてAVFoundationをインポートしています。プログラム本体としてCamViewControllerクラスを作りますが、そのクラスに対して、AVCaptureMetadataOutputObjectsDelegateのプロトコルを指定しています。これは撮影中の画像の中にQRコードなどが見つかると、自動的に呼び出されて、デコード処理などを実行するメソッドを利用可能にするものです。
このクラスのプロパティとしては、カメラのファインダーとして機能するcamView、撮影を開始するボタンとしてscanButton、デコードされたQRコードの内容を表示するラベルのdecoded、上で説明したAVCaptureSessionのsession、プレビュー用のレイヤーのlayerを定義しています。
ビューコントローラーのviewDidLoadメソッドの中では、ビューの背景色の設定の他、ファインダーとして使うイメージビュー、撮影ボタン、内容表示のラベルを初期設定して、ビューに張り付けています(図2)。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ