android - 如何将 ImageAnalyzer 类连接到应识别 qr 代码的类?
问题描述
我有两个类:QrActivity,打开相机以扫描二维码,和 BarcodeAnalyzer,图像分析过程正在进行。我正在使用 cameraX 和 ML Kit 进行操作。
那是我的 QrActivity:
package ge.softservice.nfcwithactivties
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_qr.*
import java.io.File
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class QrActivity : AppCompatActivity() {
private var preview: Preview? = null
private var imageAnalyzer: ImageAnalysis? = null
private var camera: Camera? = null
private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String>, grantResults:
IntArray
) {
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
startCamera()
} else {
Toast.makeText(
this,
"Permissions not granted by the user.",
Toast.LENGTH_SHORT
).show()
finish()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_qr)
// Request camera permissions
if (allPermissionsGranted()) {
startCamera()
} else {
ActivityCompat.requestPermissions(
this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
)
}
// outputDirectory = getOutputDirectory()
cameraExecutor = Executors.newSingleThreadExecutor()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
preview = Preview.Builder()
.build()
// Select back camera
val cameraSelector =
CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview
)
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider(/*camera?.cameraInfo*/))
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
private fun takePhoto() {
// TODO
}
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(
baseContext, it
) == PackageManager.PERMISSION_GRANTED
}
/* fun getOutputDirectory(): File {
val mediaDir = externalMediaDirs.firstOrNull()?.let {
File(it, resources.getString(R.string.app_name)).apply { mkdirs() } }
return if (mediaDir != null && mediaDir.exists())
mediaDir else filesDir
}*/
companion object {
private const val TAG = "CameraXBasic"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}
}
那是我的条码分析器:
package ge.softservice.nfcwithactivties
import android.annotation.SuppressLint
import android.content.Context
import android.widget.Toast
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import com.google.firebase.ml.vision.FirebaseVision
import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcode
import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetectorOptions
import com.google.firebase.ml.vision.common.FirebaseVisionImage
import com.google.firebase.ml.vision.common.FirebaseVisionImageMetadata
class BarcodeAnalyzer : ImageAnalysis.Analyzer {
lateinit var context: Context;
private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) {
0 -> FirebaseVisionImageMetadata.ROTATION_0
90 -> FirebaseVisionImageMetadata.ROTATION_90
180 -> FirebaseVisionImageMetadata.ROTATION_180
270 -> FirebaseVisionImageMetadata.ROTATION_270
else -> throw Exception("Rotation must be 0, 90, 180, or 270.")
}
@SuppressLint("UnsafeExperimentalUsageError")
override fun analyze(imageProxy: ImageProxy) {
// val degrees by Delegates.notNull<Int>()
val mediaImage = imageProxy.image
val imageRotation = degreesToFirebaseRotation(imageProxy.imageInfo.rotationDegrees)
if (mediaImage != null) {
val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation)
// Pass image to an ML Kit Vision API
val options = FirebaseVisionBarcodeDetectorOptions.Builder()
.setBarcodeFormats(
FirebaseVisionBarcode.FORMAT_QR_CODE
)
.build()
val detector = FirebaseVision.getInstance().getVisionBarcodeDetector(options)
val result = detector.detectInImage(image)
.addOnSuccessListener { barcodes ->
// Task completed successfully
Toast.makeText(context, "it works", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener {
// Task failed with an exception
Toast.makeText(context, "something went wrong", Toast.LENGTH_SHORT).show()
}
}
}
}
我还尝试将此代码而不是 BarcodeAnalyzer 放入 QrActivity 类中,但是无法识别图像值。
val options = FirebaseVisionBarcodeDetectorOptions.Builder()
.setBarcodeFormats(
FirebaseVisionBarcode.FORMAT_QR_CODE
)
.build()
val detector = FirebaseVision.getInstance().getVisionBarcodeDetector(options)
val result = detector.detectInImage(image)
.addOnSuccessListener { barcodes ->
// Task completed successfully
Toast.makeText(context, "it works", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener {
// Task failed with an exception
Toast.makeText(context, "something went wrong", Toast.LENGTH_SHORT).show()
}
如果我把它放在现在所在的 BarcodeAnalyzer 中,则没有错误,但结果值为灰色且未使用。
我找到了这个项目并尝试做类似的事情,但在我的项目中它显示了错误:https ://github.com/Lavanyagaur22/Visitor-Card
我也尝试了这个和其他教程,但很多事情对我来说还不清楚:https ://www.bignerdranch.com/blog/using-firebasemlkit-with-camerax/
我试图在 BarcodeAnalyzer 的 QrActivty 类中做实例,但它显示了错误。
我正在关注谷歌的 firebase ML Kit 教程,但仍然对我不起作用:https ://firebase.google.com/docs/ml-kit/android/read-barcodes#kotlin+ktx_1
那么,如何将 BarcodeAnalyzer 类连接到 QrActivity 类或如何创建一个实例来识别二维码?
解决方案
要将图像分析仪连接到相机,您需要添加一个已添加的用例;这里的预览用例:cameraProvider.bindToLifecycle(this, cameraSelector, preview)
您可以像这样创建分析器的实例:
val analyzer = ImageAnalysis.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_16_9)
.setTargetRotation(previewView.display.rotation)
.build().also {
it.setAnalyzer(Executors.newSingleThreadExecutor(), BarcodeAnalyzer())
}
然后绑定这个用例:
cameraProvider.bindToLifecycle(this, cameraSelector, preview, analyzer)
推荐阅读
- php - 删除字符串中的 char '"' 并在 php 中创建数组
- php - 数据库死锁尝试在多个表中保存数据时
- java - 参数文件上的 AS400 SQL 脚本返回
- html - CSS - 如何将 div 内的内容水平居中
- excel - 如何在文本(链接)上将数字增加 1 并创建具有实际数字但每个副本 +1 的新文本
- java - 通过每两个字符分隔将二进制字符串更改为整数
- sparql - 在 sparql 中查询年龄
- knockout.js - Magento 2 - observables 在常见的 knockoutjs 和 magento 2 框架中的工作方式是否有区别?
- unity3d - UI Hololens - HandDraggable 问题
- matlab - 如何计算矩阵 A 的列与矩阵 B 的列之间的相关性?