【问题标题】:How to use ZXing with android CameraX to decode Barcode and QR Codes如何使用 ZXing 和 android CameraX 来解码 Barcode 和 QR Codes
【发布时间】:2019-09-26 09:00:39
【问题描述】:

如何集成 ZXing 库以便与新的 Android Jetpack CameraX 一起使用?

我知道我必须构建一个 ImageAnalyzer 并在其中使用 ZXing 来解码 QR 码条码

【问题讨论】:

    标签: android kotlin zxing android-camerax


    【解决方案1】:

    ImageAnalyzer 下方,我已经建立了这样做:

    class ZxingQrCodeAnalyzer(
        private val onQrCodesDetected: (qrCode: Result) -> Unit
    ) : ImageAnalysis.Analyzer {
    
      companion object {
        val reader = MultiFormatReader()
      }
    
      /*
          https://developer.android.com/training/camerax/configuration
    
          Default resolution: The default target resolution setting is 640x480.
    
          Adjusting both target resolution and corresponding aspect ratio will result
          in a best-supported resolution under 1080p (max analysis resolution).
      */
      override fun analyze(imageProxy: ImageProxy, rotationDegrees: Int) {
        // okay - manage rotation, not needed for QRCode decoding [-;
        // okay - manage it for barcode scanning instead!!!
        try {
          imageProxy.image?.let {
            // ImageProxy uses an ImageReader under the hood:
            // https://developer.android.com/reference/androidx/camera/core/ImageProxy.html
            // That has a default format of YUV_420_888 if not changed.
            // https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888
            // https://developer.android.com/reference/android/media/ImageReader.html
            if ((it.format == ImageFormat.YUV_420_888
                || it.format == ImageFormat.YUV_422_888
                || it.format == ImageFormat.YUV_444_888)
                && it.planes.size == 3) {
              val buffer = it.planes[0].buffer // We get the luminance plane only, since we
              // want to binarize it and we don't wanna take color into consideration.
              val bytes = ByteArray(buffer.capacity())
              buffer.get(bytes)
              // Create a LuminanceSource.
              val rotatedImage = RotatedImage(bytes, imageProxy.width, imageProxy.height)
    
              rotateImageArray(rotatedImage, rotationDegrees)
    
              val source = PlanarYUVLuminanceSource(rotatedImage.byteArray,
                  rotatedImage.width,
                  rotatedImage.height,
                  0,
                  0,
                  rotatedImage.width,
                  rotatedImage.height,
                  false)
    
              // Create a Binarizer
              val binarizer = HybridBinarizer(source)
              // Create a BinaryBitmap.
              val binaryBitmap = BinaryBitmap(binarizer)
              // Try decoding...
              val result: Result
              try {
                result = reader.decode(binaryBitmap)
                onQrCodesDetected(result)
              } catch (e: NotFoundException) {
                e.printStackTrace()
              }
            } else {
              // Manage other image formats
              // TODO - https://developer.android.com/reference/android/media/Image.html
            }
          }
        } catch (ise: IllegalStateException) {
          ise.printStackTrace()
        }
      }
    
      // 90, 180. 270 rotation
      private fun rotateImageArray(imageToRotate: RotatedImage, rotationDegrees: Int) {
        if (rotationDegrees == 0) return // no rotation
        if (rotationDegrees % 90 != 0) return // only 90 degree times rotations
    
        val width = imageToRotate.width
        val height = imageToRotate.height
    
        val rotatedData = ByteArray(imageToRotate.byteArray.size)
        for (y in 0 until height) { // we scan the array by rows
          for (x in 0 until width) {
            when (rotationDegrees) {
              90 -> rotatedData[x * height + height - y - 1] =
                  imageToRotate.byteArray[x + y * width] // Fill from top-right toward left (CW)
              180 -> rotatedData[width * (height - y - 1) + width - x - 1] =
                  imageToRotate.byteArray[x + y * width] // Fill from bottom-right toward up (CW)
              270 -> rotatedData[y + x * height] =
                                imageToRotate.byteArray[y * width + width - x - 1] // The opposite (CCW) of 90 degrees
            }
          }
        }
    
        imageToRotate.byteArray = rotatedData
    
        if (rotationDegrees != 180) {
          imageToRotate.height = width
          imageToRotate.width = height
        }
      }
    }
    
    private data class RotatedImage(var byteArray: ByteArray, var width: Int, var height: Int)
    

    【讨论】:

    • 我的 camerax viewFinder 没有渲染或没有显示任何东西。请帮忙。如果你有任何 Github 链接,它将很有用
    • @ShubhamAgrawal 你看过这个吗? github.com/android/camera-samples
    • 我已经用过camerax,但是zxing lib不能用。整合这两者有什么帮助吗??
    • 只有我发现的结合CameraX和ZXing时如何调整图像旋转的清晰示例。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    相关资源
    最近更新 更多