B-Teck!

お仕事からゲームまで幅広く

【Android/Kotlin】端末内に保存されたQRコードから情報を読み取る

下記の記事の続きです blog.beatdjam.com

端末組み込みの画像一覧からQRコードの画像を取得して、テキストを読み取るまで。

端末内の画像一覧から任意の画像を取得するためのIntentを作成

画像一覧を表示し、選択した画像の情報を得るためのIntentを作成します。

/**
 * 端末内画像取得用のActivityを起動するIntentを作成
 */
fun createGetDeviceImageIntent() = Intent(Intent.ACTION_OPEN_DOCUMENT).also {
 it.addCategory(Intent.CATEGORY_OPENABLE)
 it.type = "image/*"
}

startActivityForResult() で起動することで、onActivityResult() 内で Intent::data から対象画像のUriオブジェクトを取り出すことができます。

取得したUrlからBitmap形式でファイルを取得

/**
 * 画像選択Intentから渡されたURIを用いて、Bitmap取得を行う
 */
fun getBitmapFromUri(context: Context, uri: Uri?) = when {
    uri != null -> context.contentResolver
        .openFileDescriptor(uri, "r")
        ?.use { BitmapFactory.decodeFileDescriptor(it.fileDescriptor) }
    else -> null
}

Bitmapファイルを入力としてQRコードの情報を読み取る

/**
 * bitmapからQRCode読み取りを実行
 */
fun readQRCodeFromImage(bitmap: Bitmap) = with(bitmap) {
    val pixels = IntArray(width * height)
    getPixels(pixels, 0, width, 0, 0, width, height)
    val source = RGBLuminanceSource(width, height, pixels)
    val binaryBitmap = BinaryBitmap(HybridBinarizer(source))
    MultiFormatReader().decode(binaryBitmap)?.text
}

読み取りで触ったpackageがこのあたりだったので、ZXing Android Embeddedじゃなくて生のZXing触るしかbitmapから読み込む方法がなさそうだった。

* android.graphics.Bitmap
* com.google.zxing.BinaryBitmap
* com.google.zxing.MultiFormatReader
* com.google.zxing.RGBLuminanceSource
* com.google.zxing.common.HybridBinarizer