連結QRコードの取得はZxingのライブラリそのまま使えるので難しくはない。
筆者がとび森に組んでいるコードの読み取り部分の抜粋を例に説明する。
private static final String ENCORD_NAME = "ISO-8859-1"; public byte[] decodeCameraBinQRCode(byte[] qrbmp,int width,int height) { PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(qrbmp,width,height,0,0,width,height,false); Hashtable decodeHint = new Hashtable(); decodeHint.put(DecodeHintType.CHARACTER_SET, ENCORD_NAME); decodeHint.put(DecodeHintType.TRY_HARDER, true); BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source)); Reader reader = new QRCodeReader(); Result result = reader.decode(binaryBitmap, decodeHint); public byte[] rawqrcode; byte[] dataByte = result.getText().getBytes(ENCORD_NAME); rawqrcode = result.getRawBytes(); if ((rawqrcode[0] & 0xf0) == 0x30){ int current = (rawqrcode[0] & 0x0f); code_total = ((rawqrcode[1] & 0xf0) >> 4) + 1; code_parity = ((rawqrcode[1] & 0x0f) << 4) | ((rawqrcode[2] & 0xf0) >> 4); ... }
とび森のQRコードはバイナリーデータであるため、データはバイナリーデコードしている。decodeHint回りはその設定である。
連結QRコードであるが、連結情報や連結の枚数、読み取ったQRの連結内の連番はヘッダー部分に書かれている。このヘッダー部分の情報を取得するには
rawqrcode = result.getRawBytes();
にあるgetRawBytes()関数を使用する。この関数でQRコードのヘッダー部分を含めた生データが取得できる。連結コードの場合、最初の5バイト目が以下の様になっている。
3N TP PE SS SS
- QRコードのヘッダーの0バイト目左4bitが「3」であれば連結コード
- Nが連結コード内の位置(0開始の連番)
- Tは連結コードの総数(4bitのため連結QRは最大16まで)
- PPはパリティ
- Eはエンコード種別、バイナリの場合4
- SSはQRコードのデータサイズ
パリティは8bitのため0~255であるが、これは連結QRコードのIDの役割をしている。同じ連結コードのセットの一つであるかを識別するためにこのパリティ値が使われているため、連結コード内のQRコードはすべてこのパリティが同じ値となっている。連結QRを連続して読み取る際、コード内の位置(N)とコード総数(T)と同じ連結セットか(PP)で確認する。
これが上記コード内の「current」「code_total」「code_parity」にあたる。後はひたすらQRコードの読み取りを繰り返し処理して行き、必要なQRコードのデータが揃うまでデータをためておき、全連結QRコードが揃ったら次の処理に進めば良い。
This post is also available in: 英語
kotlinを使って連結QRコードの読み込みを行いたいと思っています。
QRコードの連番はヘッダ情報にあることは理解できたのですが、ヘッダ情報が取得できずにいます。
javaでいうgetRawBytes()関数は、kotlinだとどういう風にかけるのでしょうか?
調べたところ、javaでgetXxxXxx();という関数はxxxXXXとかけると聞いたのですが、違うようでした。
下記、現在のコードです。
———————-
private fun startCapture() {
startButton?.isEnabled = false
qrReaderView?.decodeSingle(object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult?) {
stopCapture()
if (result == null) {
// no result
Log.w(TAG, “No result”)
return
}
val resultText = result.text
val bytes = result.resultMetadata[ResultMetadataType.BYTE_SEGMENTS] as? List
val data = bytes?.get(0) as? ByteArray ?: return
val resultString = StringBuffer()
data.map { byte ->
resultString.append(String.format(“0x%02X,”, byte))
}
val sequenceValue = result.resultMetadata[ResultMetadataType.STRUCTURED_APPEND_SEQUENCE] as? Int
Log.i(TAG, “QRCode STRUCTURED_APPEND_SEQUENCE: $sequenceValue”)
val parityValue = result.resultMetadata[ResultMetadataType.STRUCTURED_APPEND_PARITY] as? Int
———————————-
もし、ご存知でしたら教えていただけないでしょうか。よろしくお願い致します。