Advertisement
sphinx2001

qr code analyzer

Jun 1st, 2024
1,008
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 6.19 KB | None | 0 0
  1. package com.comsoft.code_app
  2.  
  3. import android.content.pm.PackageManager
  4. import android.graphics.Bitmap
  5. import android.os.Build
  6. import androidx.appcompat.app.AppCompatActivity
  7. import android.os.Bundle
  8. import android.util.Log
  9. import android.widget.Toast
  10. import androidx.activity.result.contract.ActivityResultContracts
  11. import androidx.camera.core.CameraSelector
  12. import androidx.camera.core.ImageAnalysis
  13. import androidx.camera.core.ImageCapture
  14. import androidx.camera.core.ImageProxy
  15. import androidx.camera.core.Preview
  16. import androidx.camera.lifecycle.ProcessCameraProvider
  17. import androidx.camera.view.PreviewView
  18. import androidx.core.content.ContextCompat
  19. import androidx.lifecycle.LifecycleOwner
  20. import com.comsoft.code_app.databinding.ActivityScanBinding
  21. import com.google.common.util.concurrent.ListenableFuture
  22. import com.google.zxing.BinaryBitmap
  23. import com.google.zxing.LuminanceSource
  24. import com.google.zxing.RGBLuminanceSource
  25. import com.google.zxing.common.HybridBinarizer
  26. import com.google.zxing.qrcode.QRCodeReader
  27. import java.nio.ByteBuffer
  28. import java.util.concurrent.ExecutorService
  29. import java.util.concurrent.Executors
  30.  
  31.  
  32. typealias QRListener = (code: String) -> Unit
  33.  
  34. class ScanActivity : AppCompatActivity() {
  35.     private lateinit var viewBinding: ActivityScanBinding
  36.     private var imageCapture: ImageCapture? = null
  37.     private lateinit var cameraExecutor: ExecutorService
  38.  
  39.     private val activityResultLauncher =
  40.         registerForActivityResult(
  41.             ActivityResultContracts.RequestMultiplePermissions())
  42.         { permissions ->
  43.             // Handle Permission granted/rejected
  44.             var permissionGranted = true
  45.             permissions.entries.forEach {
  46.                 if (it.key in REQUIRED_PERMISSIONS && it.value == false)
  47.                     permissionGranted = false
  48.             }
  49.             if (!permissionGranted) {
  50.                 Toast.makeText(baseContext,
  51.                     "Permission request denied",
  52.                     Toast.LENGTH_SHORT).show()
  53.             } else {
  54.                 startCamera()
  55.             }
  56.         }
  57.  
  58.     override fun onCreate(savedInstanceState: Bundle?) {
  59.         super.onCreate(savedInstanceState)
  60.         viewBinding = ActivityScanBinding.inflate(layoutInflater)
  61.         setContentView(viewBinding.root)
  62.  
  63.         // Request camera permissions
  64.         if (allPermissionsGranted()) {
  65.             startCamera()
  66.         } else {
  67.             requestPermissions()
  68.         }
  69.         cameraExecutor = Executors.newSingleThreadExecutor()
  70.  
  71.     }
  72.  
  73.     private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
  74.         ContextCompat.checkSelfPermission(
  75.             baseContext, it) == PackageManager.PERMISSION_GRANTED
  76.     }
  77.     private fun requestPermissions() {
  78.         activityResultLauncher.launch(REQUIRED_PERMISSIONS)
  79.     }
  80.  
  81.     private fun startCamera() {
  82.         val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
  83.  
  84.         cameraProviderFuture.addListener({
  85.             // Used to bind the lifecycle of cameras to the lifecycle owner
  86.             val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
  87.  
  88.             // Preview
  89.             val preview = Preview.Builder()
  90.                 .build()
  91.                 .also {
  92.                     it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
  93.                 }
  94.  
  95.             val imageAnalyzer = ImageAnalysis.Builder()
  96.                 .build()
  97.                 .also {
  98.                     it.setAnalyzer(cameraExecutor, QrAnalyzer { decoded_str ->
  99.                         runOnUiThread{
  100.                             viewBinding.decodedText.setText(decoded_str)
  101.                         }
  102.                     })
  103.                 }
  104.  
  105.             // Select back camera as a default
  106.             val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
  107.  
  108.             try {
  109.                 // Unbind use cases before rebinding
  110.                 cameraProvider.unbindAll()
  111.  
  112.                 // Bind use cases to camera
  113.                 cameraProvider.bindToLifecycle(
  114.                     this, cameraSelector, preview, imageAnalyzer)
  115.  
  116.             } catch(exc: Exception) {
  117.                 Log.e(TAG, "Use case binding failed", exc)
  118.             }
  119.  
  120.         }, ContextCompat.getMainExecutor(this))
  121.     }
  122.  
  123.     override fun onDestroy() {
  124.         super.onDestroy()
  125.         cameraExecutor.shutdown()
  126.     }
  127.  
  128.  
  129.     companion object {
  130.         private const val TAG = "CameraXApp"
  131.         private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
  132.         private val REQUIRED_PERMISSIONS =
  133.             mutableListOf (
  134.                 android.Manifest.permission.CAMERA,
  135.                 android.Manifest.permission.RECORD_AUDIO
  136.             ).apply {
  137.                 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
  138.                     add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
  139.                 }
  140.             }.toTypedArray()
  141.     }
  142.     private class QrAnalyzer(private val listener: QRListener) : ImageAnalysis.Analyzer {
  143.         fun BitmapToBinaryBitmap(src: Bitmap): BinaryBitmap {
  144.             val intArray = IntArray(src.width * src.height)
  145.             src.getPixels(intArray, 0, src.width, 0, 0, src.width, src.height)
  146.  
  147.             val source: LuminanceSource = RGBLuminanceSource(src.width, src.height, intArray)
  148.             return BinaryBitmap(HybridBinarizer(source))
  149.         }
  150.  
  151.         private fun ByteBuffer.toByteArray(): ByteArray {
  152.             rewind()    // Rewind the buffer to zero
  153.             val data = ByteArray(remaining())
  154.             get(data)   // Copy the buffer into a byte array
  155.             return data // Return the byte array
  156.         }
  157.  
  158.         override fun analyze(image: ImageProxy) {
  159.  
  160.             //val buffer = image.planes[0].buffer
  161.             val bitmap = image.toBitmap()
  162.             //val data = buffer.toByteArray()
  163.             var decoded_str = "Test string"
  164.             val reader = QRCodeReader()
  165.             try {
  166.                 decoded_str = reader.decode(BitmapToBinaryBitmap(bitmap)).text
  167.             } catch(e: Exception) {
  168.  
  169.             }
  170.             finally {
  171.                 listener(decoded_str)
  172.             }
  173.             image.close()
  174.         }
  175.     }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement