Android Zxing程序分析,扫码乱码解决方法

本文分析了Android Zxing库在扫码过程中的实现,包括通过摄像头和相册进行扫码的步骤,并探讨了解码线程、DecodeHandler以及如何处理扫码乱码问题。主要涉及CaptureActivity、DecodeThread、DecodeHandler和MultiFormatReader等组件的工作流程,以及针对解码错误和图片解码问题的解决策略。


一切入口从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图片算法中着手解决问题,这个有待后续研究才能解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

turbocc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值