iOSアプリでQRコードを読み込もうとしたら、QRコードが分割されている場合があることを知りました。
お薬手帳や車検証などにも使われているみたいです。
iOSアプリでその分割情報を取得する「これだ!」って方法が見つからなかったのでまとめておきます。
「いやいや、もっといい方法があるよ」という方はコメントいただけると助かります。。。
分割QRコードについて
QRコードがなんぞやっていうのは割愛します。
ググってくださいませ。
今回伝えたいのは、QRコードは分割されることがあるということです。
上記のような2つのお薬手帳用のQRコードは2つ揃って必要な情報を取得できます。
1つのQRコードが保持できる情報量は決まっているため、
上限を超える情報量を出力するためにQRコードは分割できるって話です。
分割情報はどこにある?
QRコードをバイナリにすると分かります。
バイナリ情報 | 説明 |
---|---|
1バイト目の最初4ビット | 3だと分割QRコード |
1バイト目の後ろ4ビット | 分割されているQRコードの位置(0開始) |
2バイト目の最初4ビット | 分割されているQRコードの最大位置 |
2バイト目の後ろ4ビット | パリティ1 |
3バイト目の最初4ビット | パリティ2 |
はい、シンプルですね。
見ての通りですが、分割情報が4ビットしかないので最大16分割までしかできません。
例
ここに「00110000 00011001 00110010~」で始まるQRコードがあるとします。
16進数にすると「30 19 32~」となります。
先程の表に照らし合わせると、
1バイト目の最初4ビットが3なので、このQRコードは分割されていると分かります。
1バイト目の後ろ4ビットが0なので、分割QRの1番目だと分かります。(0スタートなので1番目です)
2バイト目の最初4ビットが1なので、QRコードの総数は2つだと分かります。
2バイト目の後ろ4ビットと3バイト目の最初4ビットは、パリティです。2つ目のQRコードと同じになるのでIDっぽく使えます。
ちなみに、上記のQRコードの2つ目のバイナリ(16進表記)は以下の通りとなります。
「31 19 34~」
Swiftでどう取得するのか?
AVFoundationでQRコードを読み取るときのデリゲートメソッド内に取得方法を記載します。
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let readableObjectForQRCode = readableObject.descriptor as? CIQRCodeDescriptor else { return }
// 16進数のQRコード情報を取得
let hexQRCodeData = readableObjectForQRCode.errorCorrectedPayload.map { String(format: "%02X", $0)}
// 分割コードかチェック(trueなら分割コード)
let isSeparatedQRCode = hexQRCodeData.first!.hasPrefix("3")
// 分割コードの総数を取得
let secondByteFirstHex = hexQRCodeData[1].prefix(1) + 1
let total = Int(secondByteFirstHex, radix: 16)!
// 分割コードの位置を取得
let firstByteSecondHex = hexQRCodeData[0].suffix(1)
let position = Int(firstByteSecondHex, radix: 16)!
}
}
AVFoundationでQRコードを読み取る方法は以下記事を参考
https://qiita.com/ikaasamay/items/58d1a401e98673a96fd2
https://dev.classmethod.jp/articles/ios-avfoundation/
https://dev.classmethod.jp/articles/ios-avfoundation-avcapturemetadataoutput-qrcode/
まとめ
そのうちAppleがいい感じのメソッドを提供しそうな気もする。
でも、とりあえずQRコードの仕様が分かればそんな難しくないので別に不要な気もする。
いずれにせよ困っている人の参考になれば幸い!
参考記事