2021SC@SDUSC Zxing开源代码(六)图像解码处理

文章目录


前言

通过上篇博客的分析,我们已经明确了扫码解码的大致流程,了解了如何获取相机的一帧图像数据,并进行消息传递。这篇博客则用于详细分析在获得了图像数据后,如何进行具体的图像解码处理,其消息处理时序图如下:
2021SC@SDUSC Zxing开源代码(六)图像解码处理
首先先看一下传递的message对象,其中各个参数取值为:

参数 取值
what(消息标识) R.id.decode
arg1(整型参数) 相机分辨率的宽度
arg2(整型参数) 相机分辨率的高度
obj(传递对象) byte[] data 表示预览图像的数据

一、基础知识

二、图像解码处理

首先先看一下传递的message对象,其中各个参数取值为:

参数 取值
what(消息标识) R.id.decode
arg1(整型参数) 相机分辨率的宽度
arg2(整型参数) 相机分辨率的高度
obj(传递对象) byte[] data 表示预览图像的数据

1. DecodeHandler 处理图像解码

处理从子线程发送过来的消息 handleMessage

由于之前已经注入了处理器,则发送的消息则会传递到decodehandler的handleMessage方法中

  public void handleMessage(Message message) {
    if (message == null || !running) {
      return;
    }
    // 取消息标识头
    switch (message.what) {
      case R.id.decode:
        // 调用decode方法
        decode((byte[]) message.obj, message.arg1, message.arg2);
        break;
      case R.id.quit:
        running = false;
        Looper.myLooper().quit();
        break;
    }
  }

这里对应消息标识头为 ‘R.id.decode’ ,则调用 DecodeHandler 的decode方法,下面看一下这个方法

进行图像解码 decode

private void decode(byte[] data, int width, int height) {
    // 返回的解码结果
    Result rawResult = null;
    // 转换从相机设备中返回的YUV数据数组,可以选择性的将YUV的完整数据剪切其中一部分用于解析,以加快速度
    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
    if (source != null) {
      // 将图片进行混合二值化,创建二值化的比特位图
      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
      try {
        // 调用核心算法,返回解码结果
        rawR、esult = multiFormatReader.decodeWithState(bitmap);
      } catch (ReaderException re) {
      } finally {
        multiFormatReader.reset();
      }
    }
    Handler handler = activity.getHandler();
    if (rawResult != null) {
      if (handler != null) {
        // 创建并发送解码成功的message
        Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
        Bundle bundle = new Bundle();
        bundleThumbnail(source, bundle);
        message.setData(bundle);
        message.sendToTarget();
      }
    } else {
      if (handler != null) {
        // 创建并发送解码失败的message
        Message message = Message.obtain(handler, R.id.decode_failed);
        message.sendToTarget();
      }
    }
  }

分析来看的话,DecodeHandler 的 decode 方法主要完成了以下几个动作:

  • 首先实例化了 PlanarYUVLuminanceSource 对象,其主要作用是将传入的图像数据进行裁剪,去除掉扫描框以外的部分,以加快解码速度。
  • 而后将图片进行了二值化处理,将其赋值给一个二值比特位图
  • 将二值位图传入,调用 core.jar 的解码算法,返回解码结果
  • 发送解码成功(失败)的 message,接收方应该是 CaptureActivityHandler

2. CaptureActivityHandler 处理图像解码


总结

上一篇:C++实现简易计算器


下一篇:个人学习总结①