Android 二维码扫描 高仿微信识别率高(封装成sdk) 靠近放大 图片二维码识别 pad通用

1.二维码动画

2.zxing和zbar的区别

3.功能介绍  扫描二维码 生成logo  图片的二维码识别

4.原理和重要的类

5.扫描识别率低的问题

6.扫描二维码放大效果

7.相机框架和效果分析

 

 Android中二维码扫描的最常用库是zxing和zbar,zxing项目地址为https://github.com/zxing/zxing

目前还有多个人在维护。zbar主要用C来写的,对速度有要求的可使用zbar,但目前没有在维护,项目地址:https://github.com/ZBar/ZBar

zxing有多个人在维护,覆盖主流编程语言,也是目前还在维护的较受欢迎的二维码扫描开源项目之一。zbar则是主要用C来写的,速度极快,推出了iPhone的SDK和Android的相关调用方法(JNI),但这个项目已经有几年不维护了,目前并没有维护下去的意思,

 

二维码是什么

在研究 ZXing 之前,我一直好奇二维码是根据什么生成的,并且最大能保存多少的信息,去查阅了一下资料,正好解决了我的疑问,在此介绍一下。

二维条码是指在一维条码(条形码)的基础上扩展出另一维具有可读性的条码,使用黑白矩形图案表示二进制数据,被设备扫描后可获取其中所包含的信息。一维条码的宽度记载着数据,而其长度没有记载数据。二维条码的长度、宽度均记载着数据。二维条码有一维条码没有的“定位点”和“容错机制”。容错机制在即使没有辨识到全部的条码、或是说条码有污损时,也可以正确地还原条码上的信息。二维条码的种类很多,不同的机构开发出的二维条码具有不同的结构以及编写、读取方法。

 

 

 

 

原理步骤:

 

1获取相机的一帧图片

2.对图片进行一定的预处理,只保留亮度信息,成为灰度图像

3.对灰度图像进行二维码解析,解析成功进入下一步,不成返回步骤2

4.默认是NV21.NV21属于YUV图像,和RGB图像有所不同

 

 

整个扫描过程分为三步:相机画面预览→捕获相机预览帧数据→处理并返回帧数据

 

      根据二维码的原理,我们只需要图像的亮度信息来进行二维码解析,所以我们要把获取到的彩色图像转换为灰度图像。YUV图像转换为灰度图像的方法,以及RGB图像转换为灰度图像的方法,在后续文章中会有介绍,这里只说原理,具体实现就不再赘述。

其实条码扫描的过程很容易理解,就是将摄像头捕捉到的预览帧数组进行处理,发现其中的一维码或二维码并进行解码

 

QRCode,就是我们经常用手机扫一扫的二维码

 

二维码里面保存的信息:

 

        Zxing默认的是横屏扫码,多数情况下需要改为竖屏扫描。

提高识别

Zxing默认的是横屏扫码,多数情况下需要改为竖屏扫描。

 

CaptureActivity的配置,将Activity竖屏显示:

android:screenOrientation="portrait"

1

CameraManager类中的getFramingRectInPreview()方法,将left, right, top, bottom改变,供第4步的buildLuminanceSource内部计算使用。

//竖屏

rect.left = rect.left * cameraResolution.y / screenResolution.x;

rect.right = rect.right * cameraResolution.y / screenResolution.x;

rect.top = rect.top * cameraResolution.x / screenResolution.y;

rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;

1

 

CameraConfigurationManager类中的setDesiredCameraParameters(OpenCamera camera, boolean safeMode)方法,在setParameters之前添加,设置PreviewDisplay的方向,使SurfaceView画面方向为竖直方向。

theCamera.setDisplayOrientation(90);

--------------------- 

demo

<span style="color:#000000"><span style="color:#abb2bf">
</span></span>
<span style="color:#000000"><span style="color:#abb2bf"><span style="color:#333333"><span style="color:#ff0000"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">ScanActivity</span> <span style="color:#c678dd">extends</span> <span style="color:#e6c07b">AppCompatActivity</span> {
   <span style="color:#c678dd">private</span> CaptureManager capture;
   <span style="color:#c678dd">private</span> ImageButton buttonLed;
   <span style="color:#c678dd">private</span> DecoratedBarcodeView barcodeScannerView;
   <span style="color:#c678dd">private</span> <span style="color:#c678dd">boolean</span> bTorch = <span style="color:#c678dd">false</span>;
  <span style="color:#61aeee">@Override</span>
  <span style="color:#c678dd">protected</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onCreate</span>(Bundle savedInstanceState) {
    <span style="color:#c678dd">super</span>.onCreate(savedInstanceState);

    barcodeScannerView = initializeContent();
    buttonLed = findViewById(R.id.button_led);
    <span style="color:#929292">/*根据闪光灯状态设置imagebutton*/</span>
    barcodeScannerView.setTorchListener(<span style="color:#c678dd">new</span> DecoratedBarcodeView.TorchListener() {
        <span style="color:#61aeee">@Override</span>
        <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onTorchOn</span>() {
            buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_on));
            bTorch = <span style="color:#c678dd">true</span>;
        }

        <span style="color:#61aeee">@Override</span>
        <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onTorchOff</span>() {
            buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_off));
            bTorch = <span style="color:#c678dd">false</span>;
        }
    });
    
    <span style="color:#929292">/*开关闪光灯*/</span>
    buttonLed.setOnClickListener(<span style="color:#c678dd">new</span> View.OnClickListener() {
        <span style="color:#61aeee">@Override</span>
        <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onClick</span>(View v) {
            <span style="color:#c678dd">if</span>(bTorch){
                barcodeScannerView.setTorchOff();
            } <span style="color:#c678dd">else</span> {
                barcodeScannerView.setTorchOn();
            }

        }
    });

    capture = <span style="color:#c678dd">new</span> CaptureManager(<span style="color:#c678dd">this</span>, barcodeScannerView);

    capture.initializeFromIntent(getIntent(), savedInstanceState);

    capture.decode();
}




<span style="color:#929292">/**
 * Override to use a different layout.
 *
 * <span style="color:#c678dd">@return</span> the DecoratedBarcodeView
 */</span>
<span style="color:#c678dd">protected</span> DecoratedBarcodeView <span style="color:#61aeee">initializeContent</span>() {
    setContentView(R.layout.activity_scan);
    <span style="color:#c678dd">return</span> (DecoratedBarcodeView)findViewById(R.id.dbv);
}

<span style="color:#61aeee">@Override</span>
<span style="color:#c678dd">protected</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onResume</span>() {
    <span style="color:#c678dd">super</span>.onResume();
    capture.onResume();
}

<span style="color:#61aeee">@Override</span>
<span style="color:#c678dd">protected</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onPause</span>() {
    <span style="color:#c678dd">super</span>.onPause();
    capture.onPause();
    barcodeScannerView.setTorchOff();
}

<span style="color:#61aeee">@Override</span>
<span style="color:#c678dd">protected</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onDestroy</span>() {
    <span style="color:#c678dd">super</span>.onDestroy();
    capture.onDestroy();
}

<span style="color:#61aeee">@Override</span>
<span style="color:#c678dd">protected</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onSaveInstanceState</span>(Bundle outState) {
    <span style="color:#c678dd">super</span>.onSaveInstanceState(outState);
    capture.onSaveInstanceState(outState);
}

<span style="color:#61aeee">@Override</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">onRequestPermissionsResult</span>(<span style="color:#c678dd">int</span> requestCode, @NonNull String permissions[], @NonNull <span style="color:#c678dd">int</span>[] grantResults) {
    capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

<span style="color:#61aeee">@Override</span>
  <span style="color:#c678dd">public</span> <span style="color:#c678dd">boolean</span> <span style="color:#61aeee">onKeyDown</span>(<span style="color:#c678dd">int</span> keyCode, KeyEvent event) {
      <span style="color:#c678dd">return</span> barcodeScannerView.onKeyDown(keyCode, event) || <span style="color:#c678dd">super</span>.onKeyDown(keyCode, event);
  }
 }</code>
</span></span></span></span>

来源: https://www.jianshu.com/p/de972f5652db

 

重要的类

0.CaptureActivity

1.DecodeHandler.class中的decode()方法

2.PreviewCallback.class中的onPreviewFrame()方法

3.CameraConfigurationManager.class中的initFromCameraParameters()方法

4.CameraConfigurationUtils.class中的findBestPreviewSizeValue()方法

5.CameraConfigurationManager.class中的setDesiredCameraParameters()方法

6.CameraManager.getFramingRect()方法

7.CameraManager.class的getFramingRectInPreview()方法

 

参考博客:

https://www.jianshu.com/p/1cf060c33147

 

https://blog.csdn.net/weixin_36570478/article/details/83062172

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值