内容
Zxingを利用して端末内に保存された画像のQRコードを読み込む方法について書いています。
言語はKotlinです。この記事は該当部分を抜き出して掲載しています。
コード
最初に画像を読み込むための権限設定を書きます。Android13以降では権限関連の設定が変わったようです。(公式ドキュメント)今回は画像アクセスを行いたいのでManifest内に下記のように書きました。公式ドキュメントによるとAndroid13以降の画像取得には写真選択ツールの使用を推奨していました。この仕組みを利用したことがないので時間があるときに試してみようと思います。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
下記コードを画像の読み込みを行いたい部分(ボタンクリック時など)に指定します。こうすることで画像選択のアクティビティが表示されます。
val intent = Intent(ACTION_PICK)
intent.type = "image/*"
receivePicture.launch(intent)
Zxingを利用したQR読み込み部分
private val receivePicture =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == Activity.RESULT_OK) {
val uri = it.data?.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
val source = RGBLuminanceSource(
bitmap.width,
bitmap.height,
IntArray(bitmap.width * bitmap.height).apply {
bitmap.getPixels(this, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
})
val bitmapBinaryBitmap = BinaryBitmap(HybridBinarizer(source))
val reader = MultiFormatReader()
val result = reader.decode(bitmapBinaryBitmap)
//result.text内に取得したデータが入っているため次のアクティビティに渡す等の処理をここに書く
} else {
// アクティビティが失敗した場合の処理をここに書く
}
}
簡単な解説です。
registerForActivityResult
はアクティビティ内での動作結果を受け取っています。(公式ドキュメント)
取得したuri先の画像(Bitmap)を取得します。このgetBitmapはdeprecatedです。API Level 29以降ではImageDecoder#createSource(ContentResolver, Uri)とImageDecoder#decodeBitmap(Source)の利用が推奨されています。OSごとの分岐処理をおすすめします。(公式ドキュメント)
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
取得した画像をZXingで読み込むためにBinaryBitmapへ変換します。
val source = RGBLuminanceSource(
bitmap.width,
bitmap.height,
IntArray(bitmap.width * bitmap.height).apply {
bitmap.getPixels(this, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
})
val bitmapBinaryBitmap = BinaryBitmap(HybridBinarizer(source))
画像からデータを読み込みます。読み込んだ結果をresult内に入れます。
val reader = MultiFormatReader()
val result = reader.decode(bitmapBinaryBitmap)