cordova二维码扫码插件

作者: __damon__ | 来源:发表于2017-06-24 18:05 被阅读335次
    image.png

    插件原地址如下:
    barcode-scanner-plugin

    BarcodeScanner

    • src
      • android
        • com
        • LibraryProject
        • com.google.zxing.client.android.capture.jar
        • readme.md
          ...

    主要目录如上。
    集成说明。
    当添加插件后,会将com.google.zxing.client.android.capture.jar文件拷贝到安卓项目的libs下,作为jar包使用。是zxing的打包,原文件就在LibraryProject中。

    当你不进过修改直接使用该插件时,其扫码界面非常简陋。我们如何自定义扫码界面?

    • 修改原文件,在LibraryProject目录中。

    有两个难点,一是如何修改,二是如何打包成jar。

    打包jar

    我们先看怎么打包。
    该目录下,我们看到ant.properties这个文件和config.xml文件。
    如果你熟悉安卓开发就知道ant这个工具是做什么的,我猜测可能是打包工具,于是搜索了下ant,果然是我想的那样。


    如何使用ant?

    1. 下载ant的安装包,这里是地址,下完后解压缩。
    2. 配置环境变量(目的是使用ant命令),如何添加环境变量不多说,每个人的shell配置文件不同
    vi ~/.zshrc
    # ==> 添加下列代码(注意修改自己的路径)
    # ant
    export ANT_HOME=/Users/mrchen/Applications/apache-ant
    export PATH=$PATH:$ANT_HOME/bin
    
    1. 打开新terminal窗口,ant -version,查看是否配置正确。

    进入LibraryProject目录下,使用ant命令打包jar文件。

    cd LibraryProject
    ant ij-release
    

    生成的jar文件在:LibraryProject/bin/classes.jar
    将该文件重命名并覆盖com.google.zxing.client.android.capture.jar文件即可。

    接下来将涉及源码的修改,当你知道怎么打包jar,源码修改就好办了。

    图片变形的问题

    源码修改主要是界面图像和扫描界面。文件集中在src/com/google/zxing/client/android中,其他文件都是核心文件,如果了解zxing项目就会知道,这个插件作者整理了下,将核心和安卓代码整合起来了。

    主要做的改变是两个。

    1. 固定为竖屏
    2. 修改camera的分辨率

    文件:CameraConfigurationManager.java
    initFromCameraParameters() => 这个方法主要是初始化camera的参数

    第一步: 修改始终为竖屏(默认是横屏),将下面的代码插入到
    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
    之前,并将这一行改为
    cameraResolution = findBestPreviewSizeValue(parameters, screenResolutionForCamera);

    Point screenResolutionForCamera = new Point();
    screenResolutionForCamera.x = screenResolution.x;
    screenResolutionForCamera.y = screenResolution.y;
    // preview size is always something like 480*320, other 320*480
    if (screenResolution.x < screenResolution.y) {
      screenResolutionForCamera.x = screenResolution.y;
      screenResolutionForCamera.y = screenResolution.x;
    }
    

    第二步: 修改camera默认参数
    在方法findBestPreviewSizeValue中,会根据屏幕分辨率和摄像头默认参数(比如支持的拍摄分辨率),进行计算得到合适的camera分辨率。

    修改 MAX_PREVIEW_PIXELS 参数的默认值,该值是指定拍摄的分辨率,默认的720p。
    private static final int MAX_PREVIEW_PIXELS = 1920 * 1080; // 最大支持1080p的图片

    这里只需要在initFromCameraParameters 和 findBestPreviewSizeValue方法中修改即可。

    扫码框尺寸和位置修改

    代码位置
    CameraManager.java
    方法:Rect getFramingRect() => 获取扫码框尺寸位置参数, return rect(left, top, left, bottom);

    这里非常简单,看下源码就懂了

    修改扫码框边框和扫描线条

    代码位置
    ViewfinderView.java
    void onDraw() => 使用的是canvas画的扫描框和激光线条。示例代码如下:

    @Override
    public void onDraw(Canvas canvas) {
        if (cameraManager == null) {
          return; // not ready yet, early draw before done configuring
        }
        Rect frame = cameraManager.getFramingRect();
        if (frame == null) {
          return;
        }
        int width = canvas.getWidth();
        int height = canvas.getHeight();
    
        // Draw the exterior (i.e. outside the framing rect) darkened
        paint.setColor(resultBitmap != null ? resultColor : maskColor);
        canvas.drawRect(0, 0, width, frame.top, paint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
        canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
        canvas.drawRect(0, frame.bottom + 1, width, height, paint);
    
        // change.cf
        paint.setColor(frameAngleColor);
    
        canvas.drawRect(frame.left, frame.top, frame.left + 60, frame.top + 20, paint);
        canvas.drawRect(frame.left, frame.top, frame.left + 20, frame.top + 60, paint);
    
        canvas.drawRect(frame.right - 60, frame.top, frame.right, frame.top + 20, paint);
        canvas.drawRect(frame.right - 20, frame.top, frame.right, frame.top + 60, paint);
    
        canvas.drawRect(frame.left, frame.bottom - 60, frame.left + 20, frame.bottom, paint);
        canvas.drawRect(frame.left, frame.bottom - 20, frame.left + 60, frame.bottom, paint);
    
        canvas.drawRect(frame.right - 20, frame.bottom - 60, frame.right, frame.bottom, paint);
        canvas.drawRect(frame.right - 60, frame.bottom - 20, frame.right, frame.bottom, paint);
    
        Log.i("ViewfinderView", "**** draw rect angle ****");
    
        // change.end
    
        if (resultBitmap != null) {
          // Draw the opaque result bitmap over the scanning rectangle
          paint.setAlpha(CURRENT_POINT_OPACITY);
          canvas.drawBitmap(resultBitmap, null, frame, paint);
    
        } else {
    
          // Draw a red "laser scanner" line through the middle to show decoding is active
          paint.setColor(laserColor);
          paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
          scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
          // int middle = frame.height() / 2 + frame.top;
          // canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
    
          canvas.drawRect(frame.left + 2, frame.top + laserPosition - 4, frame.right + 2, frame.top + laserPosition + 4, paint);
    
          laserPosition += laserSpeed;
          if (laserPosition > frame.height()) {
            laserSpeed = -20;
            laserPosition = frame.height();
          }
    
          if (laserPosition < 0) {
            laserSpeed = 20;
            laserPosition = 0;
          }
    
          /*Rect previewFrame = cameraManager.getFramingRectInPreview();
          float scaleX = frame.width() / (float) previewFrame.width();
          float scaleY = frame.height() / (float) previewFrame.height();
    
          List<ResultPoint> currentPossible = possibleResultPoints;
          List<ResultPoint> currentLast = lastPossibleResultPoints;
          int frameLeft = frame.left;
          int frameTop = frame.top;
          if (currentPossible.isEmpty()) {
            lastPossibleResultPoints = null;
          } else {
            possibleResultPoints = new ArrayList<ResultPoint>(5);
            lastPossibleResultPoints = currentPossible;
            paint.setAlpha(CURRENT_POINT_OPACITY);
            paint.setColor(resultPointColor);
            synchronized (currentPossible) {
              for (ResultPoint point : currentPossible) {
                canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
                  frameTop + (int) (point.getY() * scaleY),
                  POINT_SIZE, paint);
              }
            }
          }
          if (currentLast != null) {
            paint.setAlpha(CURRENT_POINT_OPACITY / 2);
            paint.setColor(resultPointColor);
            synchronized (currentLast) {
              float radius = POINT_SIZE / 2.0f;
              for (ResultPoint point : currentLast) {
                canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
                  frameTop + (int) (point.getY() * scaleY),
                  radius, paint);
              }
            }
          }*/
    
          // Request another update at the animation interval, but only repaint the laser line,
          // not the entire viewfinder mask.
          postInvalidateDelayed(ANIMATION_DELAY,
            frame.left - POINT_SIZE,
            frame.top - POINT_SIZE,
            frame.right + POINT_SIZE,
            frame.bottom + POINT_SIZE);
        }
    }
    

    很简单,可以自己随便发挥画。注意上面代码我增加了几个变量。

    private int laserPosition = 0;
    private int laserSpeed = 20;
    private int frameAngleColor = resources.getColor(fakeR.getId("color", "frame_angle"));
    

    并且在res文件夹下的colors.xml中新增一条。

        <color name="frame_angle">#feee00</color>
    

    说明

    修改后的源代码地址 =>
    百度云

    使用方法,解压缩后,添加到cordova插件中

    cordova plugin add <your_barcode_scanner_path>

    $(function() {
      $('.scan-btn').click(function() {
    
       cordova.plugins.barcodeScanner.scan(
        function (result) {
          alert("We got a barcode\n" +
            "Result: " + result.text + "\n" +
            "Format: " + result.format + "\n" +
            "Cancelled: " + result.cancelled);
        },
        function (error) {
          alert("Scanning failed: " + error);
        },
        {
          preferFrontCamera : false, // iOS and Android
          showFlipCameraButton : false, // iOS and Android
          showTorchButton : false, // iOS and Android
          torchOn: false, // Android, launch with the torch switched on (if available)
          prompt : "Place a barcode inside the scan area", // Android
          resultDisplayDuration: 0, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
          formats : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
          orientation : "portrait", // Android only (portrait|landscape), default unset so it rotates with the device
          disableAnimations : true, // iOS
          disableSuccessBeep: false // iOS
        }
        );
     });
    });
    

    示例项目地址 =>
    coding.cordova_test
    项目比较小,测试用,不是很完整,ignore文件什么都没有配,所以插件所有文件都上传上去了的。

    示例apk下载 =>
    cordova_test.apk
    可以试试哦😁

    相关文章

      网友评论

      本文标题:cordova二维码扫码插件

      本文链接:https://www.haomeiwen.com/subject/aevkcxtx.html