コスギデンサン >> 情報系メモ >> Android

画像バーコードを読んでみる 2018/8
Target Version : 27

•Androidでバーコードを読んでみたい。
•ダウンロードして端末内にあるバーコード画像を読んでみたい。
•ボタンを押して選択した画像を表示して、可読なバーコードなら値をテキスト表示する。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.kd2.barcodetest1">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="jp.kd2.filebarcode1.MainActivity">

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Choose Barcode"
        app:layout_constraintStart_toStartOf="@+id/image_view"
        app:layout_constraintTop_toTopOf="@+id/image_view" />

    <ImageView
        android:id="@+id/image_view"
        android:scaleType="fitStart"
        android:adjustViewBounds="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txtContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:layout_gravity="left|bottom"
        android:text="barcode"
        android:background="#ffffff"/>

build.gradle
dependencies {
    ... 
    implementation 'com.google.android.gms:play-services:11.0.4+'
}

MainActivity.kt
package jp.kd2.filebarcode1

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Bitmap

import android.app.Activity
import android.view.View
import android.widget.ImageView

import java.io.IOException
import android.net.Uri
import android.widget.TextView

import com.google.android.gms.vision.Frame
import com.google.android.gms.vision.barcode.Barcode
import com.google.android.gms.vision.barcode.BarcodeDetector

class MainActivity : AppCompatActivity() {

    private val RESULT_PICK_IMAGEFILE = 100
    private var imageView: ImageView? = null
    private var detector : BarcodeDetector? = null
    private var txtView : TextView? = null

    // Activity生成時
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        detector = BarcodeDetector.Builder(applicationContext)
                .setBarcodeFormats(Barcode.DATA_MATRIX or Barcode.QR_CODE or Barcode.ISBN or Barcode.CODE_128).build()

        imageView = findViewById(R.id.image_view) as ImageView
        txtView = findViewById(R.id.txtContent)

        // ボタンクリック
        findViewById(R.id.button2).setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View) {
                val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
                intent.addCategory(Intent.CATEGORY_OPENABLE)
                intent.type = "image/*"
                // ファイル選択
                startActivityForResult(intent, RESULT_PICK_IMAGEFILE)
            }
        })
    }

    // ファイル読み込み時
    public override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {

        if (requestCode == RESULT_PICK_IMAGEFILE && resultCode == Activity.RESULT_OK) {
            var uri: Uri? = null
            if (resultData != null) {
                uri = resultData.data

                try {
                    val bitmap = getBitmapFromUri(uri)
                    imageView!!.setImageBitmap(bitmap)

                    val frame = Frame.Builder().setBitmap(bitmap).build()
                    val barcodes = detector!!.detect(frame)
                    val thisCode = barcodes.valueAt(0)

                    txtView!!.setText(thisCode.rawValue)

                    if (!detector!!.isOperational) {
                        txtView!!.setText("セットアップできません");
                        return
                    }

                } catch (e: IOException) {
                    txtView!!.setText("ファイルが読み込めません")
                    e.printStackTrace()
                } catch (e: Exception) {
                    txtView!!.setText("バーコードが読み込めません")
                    e.printStackTrace()
                }

            }
        }
    }

    // Bitmapの取得
    @Throws(IOException::class)
    private fun getBitmapFromUri(uri: Uri?): Bitmap {

        val parcelFileDescriptor = contentResolver.openFileDescriptor(uri!!, "r")
        val fileDescriptor = parcelFileDescriptor!!.fileDescriptor
        val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
        parcelFileDescriptor.close()

        return image
    }
}