一切入口从CaptureActivity 扫码窗口类开始,扫码分析一种可以通过摄像头,一种通过相册来处理,现在分别对这两种方法进行分析,以及讨论如何解决扫码乱码的问题。
1.摄像头扫码DecodeThread创建解码线程
1.1初始化摄像头initCamera
// 打开Camera硬件设备
cameraManager.openDriver(surfaceHolder);
// 创建一个handler来打开预览,并抛出一个运行时异常
if (handler == null) {
handler = new CaptureActivityHandler(this, cameraManager);
}
1.2创建CaptureActivityHandler(协调相机是否拍照成功,然后把图片抛导解码线程解码)->DecodeThread->DecodeHandler
//DecodeThread创建解码消息线程,相机拍摄完会通过DecodeHandler通知其解码。
//关联相机与解码线程
cameraManager.requestPreviewFrame(decodeThread.getHandler(), Constant.DECODE);
//拍照成功后向DecodeHandler发消息
theCamera.setOneShotPreviewCallback(previewCallback);
1.3通过触发DecodeHandler.decode方法,用multiFormatReader去解码
1.4解码成功触发事件
//获取CaptureActivityHandler把解码成功消息发回窗体CaptureActivity
Handler handler = activity.getHandler();
if (handler != null) {
Message message = Message.obtain(handler,
Constant.DECODE_SUCCEEDED, rawResult);
message.sendToTarget();
}
2.打开相册识别DecodeImgThread
2.1触发MultiFormatReader去解码
2.2解码成功触发事件
@Override
public void onImageDecodeSuccess(Result result) {
handleDecode(result);
}
3.关于MultiFormatReader
rawResult = multiFormatReader.decodeWithState(bitmap);
->MultiFormatReader 多格式读取类
->QRCodeReader 二维码格式读取类->Decoder->DecodedBitStreamParser
public final Result decode(BinaryBitmap image, Map<DecodeHintType, ?> hints) throws NotFoundException, ChecksumException, FormatException {
...
//核心解码类
if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
BitMatrix bits = extractPureBits(image.getBlackMatrix());
decoderResult = this.decoder.decode(bits, hints);
points = NO_POINTS;
} else {
DetectorResult detectorResult = (new Detector(image.getBlackMatrix())).detect(hints);
decoderResult = this.decoder.decode(detectorResult.getBits(), hints);
points = detectorResult.getPoints();
}
if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) {
((QRCodeDecoderMetaData)decoderResult.getOther()).applyMirroredCorrection(points);
}
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
...
return result;
}
->DecodedBitStreamParser图片数据流解码后,分析字符
private static void decodeByteSegment(BitSource bits, StringBuilder result, int count, CharacterSetECI currentCharacterSetECI, Collection<byte[]> byteSegments, Map<DecodeHintType, ?> hints) throws FormatException {
if (count << 3 > bits.available()) {
throw FormatException.getFormatInstance();
} else {
byte[] readBytes = new byte[count];
for(int i = 0; i < count; ++i) {
readBytes[i] = (byte)bits.readBits(8);
}
String encoding;
////////////////////////////////////////////////////////////////
//解码乱码主要是字符类型分析错误,我们在这里做一些处理就可以解决问题
//但这里是zxing的核心core,有些人不想改这里怕版本升级引起兼容性问题
//可以考虑改DecodeThread构造函数里的hints.put(DecodeHintType.CHARACTER_SET,"UTF-8");
if (currentCharacterSetECI == null) {
encoding = StringUtils.guessEncoding(readBytes, hints);
} else {
encoding = currentCharacterSetECI.name();
}
try {
result.append(new String(readBytes, encoding));
} catch (UnsupportedEncodingException var8) {
throw FormatException.getFormatInstance();
}
/////////////////////////////////////////////////////////////
byteSegments.add(readBytes);
}
}
4.zxing扫码变乱码问题有两种可能:
1.图片解码后,对字符类型分析错误,造成转码错误。这种解决方案已经在本文中说明。
2.本身图片解码出问题,如果这样就要从zxing图片算法中着手解决问题,这个有待后续研究才能解决。
本文分析了Android Zxing库在扫码过程中的实现,包括通过摄像头和相册进行扫码的步骤,并探讨了解码线程、DecodeHandler以及如何处理扫码乱码问题。主要涉及CaptureActivity、DecodeThread、DecodeHandler和MultiFormatReader等组件的工作流程,以及针对解码错误和图片解码问题的解决策略。
1879

被折叠的 条评论
为什么被折叠?



