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


public class ScanActivity extends AppCompatActivity {
   private CaptureManager capture;
   private ImageButton buttonLed;
   private DecoratedBarcodeView barcodeScannerView;
   private boolean bTorch = false;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    barcodeScannerView = initializeContent();
    buttonLed = findViewById(R.id.button_led);
    /*根据闪光灯状态设置imagebutton*/
    barcodeScannerView.setTorchListener(new DecoratedBarcodeView.TorchListener() {
        @Override
        public void onTorchOn() {
            buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_on));
            bTorch = true;
        }

        @Override
        public void onTorchOff() {
            buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_off));
            bTorch = false;
        }
    });
    
    /*开关闪光灯*/
    buttonLed.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(bTorch){
                barcodeScannerView.setTorchOff();
            } else {
                barcodeScannerView.setTorchOn();
            }

        }
    });

    capture = new CaptureManager(this, barcodeScannerView);

    capture.initializeFromIntent(getIntent(), savedInstanceState);

    capture.decode();
}




/**
 * Override to use a different layout.
 *
 * @return the DecoratedBarcodeView
 */
protected DecoratedBarcodeView initializeContent() {
    setContentView(R.layout.activity_scan);
    return (DecoratedBarcodeView)findViewById(R.id.dbv);
}

@Override
protected void onResume() {
    super.onResume();
    capture.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    capture.onPause();
    barcodeScannerView.setTorchOff();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    capture.onDestroy();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    capture.onSaveInstanceState(outState);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
      return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
  }
 }

来源: 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

 

你可能感兴趣的:(sdk开发教程)