ZXING 二维码扫描

根据 原git hub 地址 https://github.com/bingoogolapple/BGAQRCode-Android 稍作修改

ZXING扫描二维码的问题:

1.Google Zxing的二维码,条码扫描应用的是横屏的,也就是摄像头的“自然”方向。

2.扫描效果达不到微信,支付宝的效果(明显的例子就是扫描发票上的二维码,微信可以很快识别出来),可能微信是有图片增强算法的。

解决办法:

GitHub上有许多star比较高的项目

1.底层解码都是使用的ZXING的 MultiFormatReader.decodeWithState或者QRCodeReader.decode(专门识别二维码)

2.UI层主要是相机的参数设置和“取景数据”的获取。

阅读和修改源码需要注意的地方:

1.相机方向问题,也就是手机相机取景的自然方向是横屏的,所以坐标系也是横屏的,所以改到竖屏需要进行一些坐标系的转换

2.识别二维码或者条码的时候会返回识别到的“关键点”Point数组,二维码一般是上下左右四个(右下可能不返回),如果需要现实到UI也要对这些点进行一下坐标转化才能现实出来。

比较好的项目有

1. https://github.com/qingmei2/QrCodeScannerView-Android 专门识别二维码的,感觉上很快但是看代码没看出快在哪里(可能是直接用QRCodeReader直接解码的原因)

2.https://github.com/bingoogolapple/BGAQRCode-Android,这个star很多,UI功能做的很完整,适合直接拿过来用的,不过我在使用的时候遇到了BUG,主要是两个问题,局部(扫描框)取景数据的问题,和返回识别“关键点”坐标不准确的问题,自己动手解决了一下,测试了,还是不错的。更改了两个地方如下。

1.ScanBoxView.java 解决扫描框取景数据的问题

public Rect getScanBoxAreaRect(int previewHeight) {
        if (mIsOnlyDecodeScanBoxArea && getVisibility() == View.VISIBLE) {
            Rect rect = new Rect(mFramingRect);
            float ratio = 1.0f * previewHeight / getMeasuredHeight();

            float centerX = rect.exactCenterX();
            float centerY = rect.exactCenterY();

            float halfWidth = rect.width() / 2f;
            float halfHeight = rect.height() / 2f;
            float newHalfWidth = halfWidth * ratio;
            float newHalfHeight = halfHeight * ratio;
            //原来没有*ratio
            rect.left = (int) (centerX * ratio - newHalfWidth);
            rect.right = (int) (centerX * ratio + newHalfWidth);
            rect.top = (int) (centerY * ratio - newHalfHeight);
            rect.bottom = (int) (centerY * ratio + newHalfHeight);
            return rect;
        } else {
            return null;
        }
    }

2.QRCodeView.java 解决“关键点”坐标不准确的问题

 /**
     * 坐标转换,得到扫描有效point
     * 已经修改BUG
     * @param originX
     * @param originY
     * @param cameraPreviewWidth
     * @param cameraPreviewHeight
     * @param isMirrorPreview
     * @param statusBarHeight
     * @param scanBoxAreaRect
     * @return
     */
    private PointF transform(float originX, float originY, float cameraPreviewWidth, float cameraPreviewHeight, boolean isMirrorPreview, int statusBarHeight,
                             final Rect scanBoxAreaRect) {
        int viewWidth = getWidth();
        int viewHeight = getHeight() + statusBarHeight;

        PointF result;
        float scaleX;
        float scaleY;

        if (BGAQRCodeUtil.isPortrait(getContext())) {
            scaleX = viewWidth / cameraPreviewHeight;
            scaleY = viewHeight / cameraPreviewWidth;
            result = new PointF(originX * scaleX, originY * scaleY);//(1080-280)*1440/1080,(1920-320)*2660/1920
        } else {
            scaleX = viewWidth / cameraPreviewWidth;
            scaleY = viewHeight / cameraPreviewHeight;
            result = new PointF(originX * scaleX, originY * scaleY);
            if (isMirrorPreview) {
                result.x = viewWidth - result.x;
            }
        }

        if (scanBoxAreaRect != null) {
            result.y += scanBoxAreaRect.top * scaleX;
            result.x += scanBoxAreaRect.left * scaleY;
        }
        return result;
    }

 

你可能感兴趣的:(解决问题总结)