LoginSignup
0
0

More than 1 year has passed since last update.

ZXingで画像からQRコードを読み込む【Kotlin】

Posted at

内容

Zxingを利用して端末内に保存された画像のQRコードを読み込む方法について書いています。
言語はKotlinです。この記事は該当部分を抜き出して掲載しています。

コード

最初に画像を読み込むための権限設定を書きます。Android13以降では権限関連の設定が変わったようです。(公式ドキュメント)今回は画像アクセスを行いたいのでManifest内に下記のように書きました。公式ドキュメントによるとAndroid13以降の画像取得には写真選択ツールの使用を推奨していました。この仕組みを利用したことがないので時間があるときに試してみようと思います。

AndroidManifest.xml
<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)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0