CameraX Qrcode扫描仪检测到错误

原学程将引见CameraX Qrcode扫描仪检测到毛病的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。

CameraX Qrcode扫描仪检测到错误 教程 第1张

成绩描写

您佳,我用CameraX开辟了1个简略的两维码扫描器。它不妨任务,但是我想在Qrcode四周展现1个预览外形。
我创立了1个定制的望图并收送条形码的界限框,然则..尺寸以及地位毛病。

我以为这是1个坐标翻译成绩。或许:(

这里有1个小项目
https://github.com/giuseppesorce/cameraxscan

部门代码:

package com.gs.scancamerax

import android.Manifest.permission.CAMERA
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.谷歌.mlkit.vision.barcode.BarcodeScanning
import com.谷歌.mlkit.vision.co妹妹on.InputImage
import com.gs.scancamerax.databinding.FragmentScanBarcodeBinding


import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

typealias BarcodeListener = (barcode: String) -> Unit


class ScanBarcodeFragment : Fragment() {
 private var scanningResultListener: ScanningResultListener? = null
 private var flashEnabled: Boolean = false
 private var camera: Camera? = null
 private var processingBarcode = AtomicBoolean(false)
 private lateinit var cameraExecutor: ExecutorService
 private var _binding: FragmentScanBarcodeBinding? = null
 private val binding get() = _binding!!
 private val TAG = "CameraXBasic"
 private val RATIO_四_三_VALUE = 四.0 / 三.0
 private val RATIO_一六_九_VALUE = 一六.0 / 九.0
 private var imageCapture: ImageCapture? = null
 private var imageAnalyzer: ImageAnalysis? = null
 private var cameraProvider: ProcessCameraProvider? = null


 override fun onCreateView(
  inflater: LayoutInflater,
  container: ViewGroup?,
  savedInstanceState: Bundle?
 ): View? {
  _binding = FragmentScanBarcodeBinding.inflate(inflater, container, false)
  val view = binding.root
  return view
 }

 override fun onResume() {
  super.onResume()
  processingBarcode.set(false)
 initFragment()
 }


 private fun startCamera() {
  val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
  cameraProviderFuture.addListener(Runnable {
// CameraProvider
cameraProvider = cameraProviderFuture.get()
// Build and bind the camera use cases
bindCameraUseCases()
  }, ContextCompat.getMainExecutor(requireContext()))
 }



 private fun aspectRatio(width: Int, height: Int): Int {
  val previewRatio = max(width, height).toDouble() / min(width, height)
  if (abs(previewRatio - RATIO_四_三_VALUE) <= abs(previewRatio - RATIO_一六_九_VALUE)) {
return AspectRatio.RATIO_四_三
  }
  return AspectRatio.RATIO_一六_九
 }

 private var preview: Preview? = null
 private fun bindCameraUseCases() {

  // Get screen metrics used to setup camera for full screen resolution
  val metrics =
DisplayMetrics().also { binding.fragmentScanBarcodePreviewView.display.getRealMetrics(it) }
  Log.d(TAG, "Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")

  val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
  Log.d(TAG, "Preview aspect ratio: $screenAspectRatio")

  val rotation = binding.fragmentScanBarcodePreviewView.display.rotation

  // CameraProvider
  val cameraProvider = cameraProvider
?: throw IllegalStateException("Camera initialization failed.")

  // CameraSelector
  val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()

  // Preview
  preview = Preview.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation
.setTargetRotation(rotation)
.build()

  // ImageCapture
  imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
// We request aspect ratio but no resolution to match preview config, but letting
// CameraX optimize for whatever specific resolution best fits our use cases
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.build()

  // ImageAnalysis
  imageAnalyzer = ImageAnalysis.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.build()
// The analyzer can then be assigned to the instance
.also {
 it.setAnalyzer(cameraExecutor, BarcodeAnalyzer { luma ->
  // Values returned from our analyzer are passed to the attached listener
  // We log image analysis results here - you should do something useful
  // instead!
  Log.d(TAG, "Average luminosity: $luma")
 })
}

  // Must unbind the use-cases before rebinding them
  cameraProvider.unbindAll()

  try {
// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
 this, cameraSelector, preview, imageCapture, imageAnalyzer
)

// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(binding.fragmentScanBarcodePreviewView.surfaceProvider)
  } catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
  }
 }


 private var lensFacing: Int = CameraSelector.LENS_FACING_BACK


 private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
  ContextCompat.checkSelfPermission(
requireContext(), it
  ) == PackageManager.PERMISSION_GRANTED
 }

  fun initFragment() {
  cameraExecutor = Executors.newSingleThreadExecutor()
  if (allPermissionsGranted()) {
binding.fragmentScanBarcodePreviewView.post {
 startCamera()
}
  } else {
requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
  }
 }

 override fun onRequestPermissionsResult(
  requestCode: Int, permissions: Array<String>,
  grantResults: IntArray
 ) {
  if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
 startCamera()
} else {
 activity?.let {
  Toast.makeText(
it.applicationContext,
"Permissions not granted by the user.",
Toast.LENGTH_SHORT
  ).show()
 }
}
  }
 }

 private fun searchBarcode(barcode: String) {
  Log.e("driver", "searchBarcode: $barcode")
 }

 override fun onDestroy() {
  cameraExecutor.shutdown()
  camera = null
  _binding = null
  super.onDestroy()
 }


 inner class BarcodeAnalyzer(private val barcodeListener: BarcodeListener) :
  ImageAnalysis.Analyzer {

  private val scanner = BarcodeScanning.getClient()
  @SuppressLint("UnsafeExperimentalUsageError")
  override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image
if (mediaImage != null) {
 val image =
  InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
 // Pass image to the scanner and have it do its thing
 scanner.process(image)
  .addOnSuccessListener { barcodes ->

for (barcode in barcodes) {

 barcodeListener(barcode.rawValue ?: "")
 binding.myView.setBounds(barcode.boundingBox)
}
  }
  .addOnFailureListener {
// You should really do something about Exceptions
  }
  .addOnCompleteListener {
// It's important to close the imageProxy
imageProxy.close()
  }
}
  }
 }

 override fun onDestroyView() {
  super.onDestroyView()
  _binding = null
 }

 fun setScanResultListener(listener: ScanningResultListener) {
  this.scanningResultListener = listener
 }

 companion object {
  private val REQUIRED_PERMISSIONS = arrayOf(CAMERA)
  private const val REQUEST_CODE_PERMISSIONS = 一0
  const val TAG = "BarCodeFragment"

  @JvmStatic
  fun newInstance() = ScanBarcodeFragment()
 }
}

推举谜底

没有肯定您能否依然有这个成绩,但是如今CameraX供给了1个名为CoordinateTransform的助脚类,它将坐标从1个用例转换到另外一个用例。比方,您不妨将从ImageAnalysis检测到的两维码的边框转换为预览望图坐标,并在那边画制1个边框。

// ImageProxy is the output of an ImageAnalysis.
OutputTransform source = ImageProxyTransformFactory().getOutputTransform(imageProxy);
OutputTransform target = previewView.getOutputTransform();

// Build the transform from ImageAnalysis to PreviewView
CoordinateTransform coordinateTransform = new CoordinateTransform(source, target);

// Detect barcode in ImageProxy and transform the coordinates to PreviewView.
RectF boundingBox = detectBarcodeInImageProxy(imageProxy);
coordinateTransform.mapRect(boundingBox);

// Now boundingBox contains the coordinates of the bounding box in PreviewView.

佳了闭于CameraX Qrcode扫描仪检测到毛病的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。