文章目录
前言
通过上篇博客的分析,我们已经明确了扫码解码的大致流程,了解了如何获取相机的一帧图像数据,并进行消息传递。这篇博客则用于详细分析在获得了图像数据后,如何进行具体的图像解码处理,其消息处理时序图如下:
首先先看一下传递的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