Zxing库的使用及拓展(自动变焦)

解锁未来:探秘Zxing二维码技术的神奇世界 Zxing是一项由Google开发和维护的开源二维码处理库,旨在为开发者提供强大而灵活的二维码识别、生成和解析功能。作为业界领先的二维码技术之一,Zxing在各个领域都有着广泛的应用。背景和起源:Zxing最初于2006年由Google工程师Sean Owen和其他贡献者创建,并于2007年开源发布。其名字来源于“zebra crossing”,意味着像斑马线一样将信息从纸质世界转移到数字世界。Zxing的初衷是为了简化二维码的处理和识别过程,使其更加普及和便捷。 阅读详情

前言

源码版本:3.3.2

源码地址:https://github.com/zxing/zxing/tree/master/android

案例地址:https://github.com/LMW-ICodeMan/Open-Source-Code-For-Android/tree/master/QRcodeProjects

本次调研的二维码扫描的库为Zxing,在进行二维码解析库的选择时对比Zxing和Zbar,发现Zbar的解析效率较Zxing高,但是长期没有人对Zbar的库进行维护,且很难实现本次调研的主要目的(根据图像识别的结果进行自动变焦),所以选择使用Zxing库。

带着问题学习

本次调研需要解决的问题包括如下内容:

  1. 详细了解二维码解析的详细流程
  2. 尽可能加快二维码解析的速度
  3. 实现自动变焦的功能

在这些功能中,我们的主要目的是实现摄像头自动变焦,调研发现,Zxing在解析二维码图片时,会返回解析到特征点信息,且这些信息中带有这些点在我们传入帧图中的相对位置,我们可以根据这些特征点信息计算出二维码在帧图中的大小,然后来控制摄像头进行变焦。

针对解读源码前的相关调研,接下来会带着如下几个问题去阅读Zxing的源码时:

  1. 图片流传入Zxing以前需要经过哪些处理?
  2. Zxing是如何解析图片的?
  3. 特征点是如何获得的?
  4. 对于不存在二维码的帧图或者二维码存在不全的帧图,是否能让特征点信息返回?
  5. 影响解析效率的因素有哪些?怎么合理优化?

库介绍

本次使用到的库有两个:BGAQRCode-Android、Zxing

根据实际需求,针对库中的代码进行了修改,其中主要包括:

  • BGAQRCode-Android

    1. 去掉了与条形码相关的代码
    2. 修改了对焦频率、降低了帧图监听的延迟
    3. 一些与Zxing相关的性能优化(选择)
    4. 添加了部分日志
  • Zxing

    1. 添加FoundPartException类型。
    2. 修改FinderPatternFinder的selectBestPatterns(),在发现特征点不全的情况下,抛出异常并返回已经发现的特征点。
    3. 修改Detector类的相关方法,添加 throw FoundPartException。

问题解读

在解读Zxing相关的源码前,我们需要对这几个概念有一定的了解

  • 一维码和二维码(来自联图)

一维码就是我们见到的条形码,这种条形码的特点就是它所包含的信息在水平方向上,竖直方向上不包含信息,且一维码包含的信息只能包含字母和数字,且遭到损坏后便不能阅读了。

二维码就是我们这次调研的对象,它的信息存储在水平和竖直两个方向上,比条形码容纳的信息量大,且保密性和可靠性比条形码强,由于二维码中包含有冗余信息,所以就算局部损坏或穿孔,依然可以正确的识别。

一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,最常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(BINARIZATION)。

图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。

  • 数码变焦和光学变焦(来自ZOL)

简单的理解就是数码变焦是通过放大单位像素来实现放大缩小,光学变焦则是通过镜头的相对位置调整物理焦距实现放大缩小。所以数码变焦是损耗图片质量的,而我们的手机大部分都是数码变焦。

因此,我们实现变焦后传入的图片在质量上有损耗,但是单位像素所包含的信息量也变少了,有助于识别的算法更快、更准确的识别二维码内容。(讲道理,如果放大后的图片能识别到二维码,那不放的也应该是可以的,但是较放大后的图片来说识别度较低,识别速度较慢,会严重影响用户体验)

Zxing解析之前的准备

首先,我们通过预览回调onPreviewFrame方法获取每一帧的图片,然后开线程对图片进行处理,由于异步任务的特性,在task.cancel后并没有真正意义上的停止线程,而onPreviewFrame()的回调是特别频繁的,为了避免多个线程同时执行图像解析方法造成内存问题,在异步线程中加上了同步锁判断,主要方法如下:

ProcessDataTask.class


    @Override
    protected String doInBackground(Void... params) {
        if(!BarcodeLockUtil.requestLock()){
            return null;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        Camera.Size size = parameters.getPreviewSize();
        int width = size.width;
        int height = size.height;

//        byte[] rotatedData = new byte[mData.length];
//        for (int y = 0; y < height; y++) {
//            for (int x = 0; x < width; x++) {
//                rotatedData[x * height + height - y - 1] = mData[x + y * width];
//            }
//        }
//        int tmp = width;
//        width = height;
//        height = tmp;

        try {
            if (mDelegate == null) {
                return null;
            }
            return mDelegate.processData(mData,orientation,width, height, false);
        } catch (Exception e1) {
            try {
                return mDelegate.processData(mData,orientation,width, height, true);
            } catch (Exception e2) {
                return null;
            }
        } finally {
            BarcodeLockUtil.releaseLock();
        }
    }

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

接下来就是将图片流传入Zxing的解析接口的工作了,在使用Zxing的接口之前,我们需要对于其需要的几个类有一个认识:

  • LuminanceSource 
    这个类的子类封装了一些方法来用来获取帧图中的信息,主要方法有:getRow(),getMatrix(),crop()。所得到的都是原图的byte数组,没有对其中的像素点信息进行处理。

  • Binarizer 
    这个类的子类主要用于将LuminanceSource进行二值化操作并转化成BitArray/BitMatrix类型,主要方法包括:getBlackRow(),getBlackMatrix(),createBinarizer()。

  • BinaryBitmap 
    这个类是可以看做是对Binarizer的一次再封装,这个类就是一个是解析时直接使用的实体类,其中的所有方法都是公开方法。

  • Reader 
    这个接口是所有解析类都需要继承的接口,核心方法为两个decode()方法,主要负责对BinaryBitmap中的BitArray进行解析并返回解析结果。

下面是在线程中实际执行解析的方法:

ZxingView.class


private QRCodeReader reader = new QRCodeReader();

@Override
public String processData(byte[] data,int orientation,int width, int height, boolean isRetry) {
    Result rawResult = null;
    try {
        PlanarYUVLuminanceSource source = null;
        Rect rect = null;
        if(orientation == BGAQRCodeUtil.ORIENTATION_PORTRAIT) {
            rect = mScanBoxView.getScanBoxAreaRect(width);
            source = new PlanarYUVLuminanceSource(data, width, height, rect.top, rect.left, rect.height(), rect.width(), false);
        }else {
            rect = mScanBoxView.getScanBoxAreaRect(height);
            source = new PlanarYUVLuminanceSource(data,width,height,rect.left,rect.right,rect.width(),rect.height(),false);
        }
        rawResult = reader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        reader.reset();
    }
    if(rawResult != null){
        return rawResult.getText();
    }else {
        return null;
    }
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

Zxing解析二维码的步骤&自动变焦的契机

我们将二值化的图片传入Zxing的Detector后,下面两段代码是在解析时最关键的两个类:

Detector.class

  public final DetectorResult detect(Map<DecodeHintType,?> hints) throws NotFoundException, FormatException, FoundPartException {

    resultPointCallback = hints == null ? null :
        (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);

    FinderPatternFinder finder = new FinderPatternFinder(image, resultPointCallback);
    FinderPatternInfo info = finder.find(hints);

    return processFinderPatternInfo(info);
  }
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

FinderPatternFinder.class

  final FinderPatternInfo find(Map<DecodeHintType,?> hints) throws NotFoundException, FoundPartException {
    ...

    FinderPattern[] patternInfo = selectBestPatterns();
    ResultPoint.orderBestPatterns(patternInfo);

    return new FinderPatternInfo(patternInfo);
  }

  private FinderPattern[] selectBestPatterns() throws NotFoundException, FoundPartException{

    int startSize = possibleCenters.size();

    if (startSize < 3) {
      if(startSize > 0){
        FoundPartException exception = FoundPartException.getFoundPartInstance();
        exception.clear();
        for (FinderPattern fp:possibleCenters){
          exception.addPattern(fp);
        }
        throw exception;
      }
      // Couldn't find enough finder patterns
      throw NotFoundException.getNotFoundInstance();
    }

    ...
  }

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

从detect方法中我们可以看到,QRCode的解码过程大致分为两步:找到特征点,然后处理结果(processFinderPatternInfo后面的步骤包括了数据校验和生成最终的矩阵)。调试后发现,find方法只会在识别到了二维码之后才会返回,这明显不是我们需要的,所以,为了实现自动变焦,我们重点需要去改变的是find中的内容。

在find中,开始一大段内容省略的是获取特征点的算法,很复杂,还没有达到能修改这部分算法的层次。但是!它拿到特征点后进行了两个操作:selectBestPatterns()这个方法内部实现,可以发现原来它原来是这么一段:

    if (startSize < 3) {
      // Couldn't find enough finder patterns
      throw NotFoundException.getNotFoundInstance();
    }
 
  • 1
  • 2
  • 3
  • 4

So,当解析到的二维码信息不全时,会直接抛出NotFoundException的异常,我们需要实现自动变焦,就可以考虑在这里拿到它已经找的特征点信息并返回给上层,所以便有了我们上面的代码,在其中插入一段判断,抛出一个不同的异常。其中FoundPartException就是我们自己添加的内容,写法参照了NotFoundException:

public class FoundPartException extends ReaderException {

    private static final FoundPartException INSTANCE = new FoundPartException();

    static {
        INSTANCE.setStackTrace(NO_TRACE); // since it's meaningless
    }

    private List<ResultPoint> foundPoints;

    private FoundPartException() {
        // do nothing
        foundPoints = new ArrayList<>();
    }

    public void clear(){
        foundPoints.clear();
    }

    public void addPattern(ResultPoint point) {
        foundPoints.add(point);
    }

    public void addPatterns(List<ResultPoint> points){
        foundPoints.addAll(points);
    }

    public List<ResultPoint> getFoundPoints() {
        return foundPoints == null ? new ArrayList<ResultPoint>() : foundPoints;
    }

    public static FoundPartException getFoundPartInstance() {
        return INSTANCE;
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

影响解析效率的因素&能力范围内的优化

在进行解析的过程中,测试发现有如下内容对效率的影响比较明显:

  1. 二值化的工具选择
  2. 解码格式的选择
  3. 图片流的旋转处理
  4. 并发线程的影响
  5. 解析二维码的算法

其中,我们能够做到的优化是针对1-4的,算法的修改过于麻烦,风险也较大,没有做任何修改。(革命尚未成功,同志仍需努力!)

下面是优化性能/提高代码可读性的内容:

  1. 删除了ProcessDataTask中关于图片旋转的方法(这一步很关键,测试发现这一步在大型应用中严重影响效率,下面对异步线程的优化中有详细介绍)
  2. 删除了BGAQRCode-Android中与二维码无关的代码
  3. 为ProcessDataTask添加了线程锁
  4. 解析器使用QRCodeReader(只能识别二维码)
  5. 使用GlobalHistogramBinarizer对原数据进行二值化(消耗cpu更低)
  6. 提高了自动对焦的频率(有助于变焦后快速识别)
对异步线程的优化

除了加入同步锁,与BGAQRCode-Android相比,这里还做了一个处理,就是去除了竖屏状态下翻转屏幕的算法代码,原因是这段算法在导入到比较大的应用(MOA)中后,执行时间在500ms左右,严重影响到了整体解析速度。

        byte[] rotatedData = new byte[mData.length];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                rotatedData[x * height + height - y - 1] = mData[x + y * width];
            }
        }
        int tmp = width;
        width = height;
        height = tmp;
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

PS:在独立App下面多次测试发现,加入此段代码,在竖屏且无二维码图时,cpu的波动增加了3-5%(通过AS监控波动峰值得到),内存的波动增加了2M(通过AS监控波动峰值得到),最终决定弃用这段代码,通过其他手段去解决横竖问题。

总结

本次针对二维码扫描功能的优化到此就算结束了,本次针对二维码的研究,除了完成任务外,对于二维码、图像识别、Camera相关的内容都有了较深入的学习和了解,总结了这次优化能为我们带来的良性影响如下:

  1. 从现有效果来说,与项目中的原有的zbar的解析相比,新的库表现出来的解析速度丝毫不逊色,并且新库在旋转角度、图像变形和远距的场景中表现远远优胜于原来的库。

  2. 从长远效果来说,ZXing的库在持续更新,无论是算法的优化还是新的解析格式的添加都是紧跟潮流,相反Zbar的维护工作已经停止,从未来的拓展性来考虑,Zxing的实用性远高于Zbar。

鸣谢

https://github.com/bingoogolapple/BGAQRCode-Android 
https://github.com/zxing/zxing 
http://www.liantu.com/zhishi/2012070322.html 
https://baike.baidu.com/item/%E4%BA%8C%E5%80%BC%E5%8C%96/4766301?fr=aladdin 
http://mobile.zol.com.cn/413/4134487_all.html 
https://www.cnblogs.com/riasky/p/3508874.html

Android开发--Zxing库实现二维码/条形码扫描识别 阅读详情

相关推荐

VS2019 配置ZXing解码库+OpenCV4.1成功案例

一、前言 刚刚转到windows下面的环境下,OpenCV库已经配置好了,接下来需要配置二维码解码库了。 二、环境 系统:Win10 VS2019 OpenCV 4.1 ZXing 三、配置过程 3.1 预先配置 先安装好VS2019,并配置好OpenCV4,这个网上一大堆教程,不再赘述。 3.2 安装CMake 在CMake官网下载安装即可,注意将其添加进系统环境变量。 3.3用CMake编译...

小膜仙的博客 3435

使用zxing来生成二维码

在使用zxing生成二维码时,我们需要先准备好相关的依赖和jar包,并使用QRCodeWriter类来生成普通的二维码。无论是生成普通的二维码还是带有Logo的二维码,zxing都是一个非常实用的工具。而在二维码的生成过程中,zxing是一款非常优秀的开源库,它提供了一系列的API,可以帮助我们快速、方便地生成二维码。在使用zxing生成二维码之前,我们需要先下载zxing的jar包,并将其导入到项目中。除了普通的二维码之外,我们还可以生成带有Logo的二维码。三、生成带有Logo的二维码。

qinshengfei的专栏 6078

android项目内导入zxing库

android项目内导入zxing库亲测有效 第一篇博客,虽然有点羞涩但是确实还是想记录一下学习zxing导入的使用方法,简单实现一下生成二维码与扫描二维码的功能,后期会继续出生成二维码与扫描二维码的文章,刚开始接触网上的很多博客找了好像用处都不大,亲测有效吧。新手勿喷。 1.将github内的android包import model 2.导入zxing包内的android库 3.在zxing的build包内导入zxing依赖包。 implementation ‘com.google.zxing:zx

qq377138858的博客 4624

zxing的使用及优化

二维码介绍 zxing项目是谷歌推出的用来识别多种格式条形码的开源项目,项目地址为https://github.com/zxing/zxing,zxing有多个人在维护,覆盖主流编程语言,也是目前还在维护的较受欢迎的二维码扫描开源项目之一。 zxing的项目很庞大,主要的核心代码在core文件夹里面,也可以单独下载由这个文件夹打包而成的jar包,具体地址在http://mvnreposit

lambert 7万+

使用ZXing.dll库生成二维码(C#实现)

最近工作中有需要一个需求,就是把一个服务地址生成二维码,可以用来扫码分享,网上找了下方法也比较多,我这里po一下调用ZXing.dll库生成二维码的方法吧。先简单介绍一下 ZXing库,ZXing库是一个开源Java类库,可用于生成和解析多种格式的1D/2D条形码;zxing遵循Apache License 2.0,只是工具而已,是不收费哒。 ZXing库的下载地址:http://zxingne...

weixin_30847271的博客 1874

ios上ZXing库的配置流程

步骤         首先,用Xcode创建我们的demo, 取名TestZXing(根据自己的喜好随便取)。找到项目的位置,打开文件夹,在里面创建一个文件夹取名zxing, 如图: 然后从https://github.com/zxing/zxing上把zxing下载下来。解压打开。由于zxing支持多个平台,而我们只需要支持ios的就行,所以我们只需要保留两个文件夹(cpp和iphone

louercab的专栏 1778

第三方ZXing库zxing-android-embedded使用及自定义

一、关于ZXing现在一维码二维码在我们的日常生活中使用如此的广泛,所以拥有扫码功能的APP变得非常普遍,一个安卓APP需要扫码功能就要用到zxing了,zxing是谷歌开源的让开发者更方便使用摄像头的库,而我们常用的扫码功能就是其中之一。github地址:https://github.com/zxing/zxing但是因为zxing的功能太强大了,包含了很多我们用不上的功能,所以一般都会抽取其中的

u010618194的博客 3万+

使用zxing库——遇到复印机打印的条形码无法识别的问题分析

支持多种编程语言(如Java、C++、Python等),主要用于生成、扫描和解析各类一维/二维条码。是一个基于 Vue.js 的库,专门用于在网页应用中实现二维码(QR Code)的扫描和解析功能。使用zxing库——遇到复印机打印的条形码无法识别的问题分析。)是一个开源的、多平台的。

Enya61的博客 1269

ZXing-JS 库使用教程

ZXing-JS 是一个用于二维码和条形码处理的 JavaScript 库。以下是其主要目录结构及其功能介绍: ``` zxing-js/ ├── docs/ # 文档目录 ├── examples/ # 示例代码 ├── src/ # 源代码目录 │ ├── core/ # 核心功能代...

gitblog_00291的博客 1863

Android Studio 接入ZXing依赖库全流程

接触Android Studio时间不是很久,对此也不太熟悉。用习惯之后真心感觉不错,Android Studio也是一种趋势,所以也开始学习学习,一看到Android Studio就高大上,同时也很复杂,至今都没彻底搞懂。最近接触到二维码接入,期间遇到好多问题,在网上找了很久资料,都是很零散的。被折腾了三天,最终弄出来了。在此分享经验,好让以后我忘了可以翻一翻看看,当作是经验记录。希望可以得到大牛

YegodYue的博客 8662

【深度解析】Zxing:开源条形码图像处理库的领航者

Zxing作为一款成熟且功能全面的开源条形码图像处理库,凭借其优秀的性能、广泛的格式支持和易用性,已成为众多企业和个人开发者在条形码识别和生成领域的首选工具。无论是初学者还是经验丰富的开发者,Zxing都能提供所需的一切,帮助你构建高效、可靠的条形码处理系统。未来,随着技术的不断进步,Zxing也将持续演进,为用户提供更多创新功能,推动条形码技术的发展。如果你正寻找一款强大而灵活的条形码处理库,Zxing无疑是最佳选择之一。

u013558123的博客 3294

Android Studio使用zxing库扫描并解析条形码

首先导入zxing库,打开app下的build.gradle位置如下。   打开后在如下位置后,在dependencies中 添加划线的那行代码,即: compile 'com.journeyapps:zxing-android-embedded:3.5.0'   解析条形码   1.在xml中写入控件,我这里是一个TextView用来接收返回的ISBN码和一个Button

Satan的博客 1万+

zxing 二维码扫描demo +js二维码生成demo

手机端 zxing 二维码扫描,web端js二维码生成

Android ZXing(二维码)库的全面使用解析

Android ZXing(二维码)库解析 本文原创,转载请注明出处。 欢迎关注我的 简书 ,关注我的专题 Android Class 我会长期坚持为大家收录简书上高质量的 Android 相关博文。 写在前面:春天到了,天气转暖,风吹走了北京的雾霾也带来了困倦。每天感觉就是睡不醒、起不来。前一阵研究了 View 的体系,还差滑动冲突和 View 的绘制没有落笔成文,还看了很多关于 MVP

MeloDev的博客 5052

麒麟银河操作系统V10下ffmpeg的完整部署指南(兼容Linux系统)

本文提供在麒麟银河操作系统V10上从源码编译部署FFmpeg的完整指南,涵盖环境准备、核心依赖库(如x264)编译、FFmpeg本体配置安装、系统集成及常见问题排查。步骤详细,同样适用于Ubuntu、CentOS等主流Linux发行版,帮助用户打造功能强大的多媒体处理工具链。

weixin_29205061的博客 256

开源Agent Skill让AI画图不再翻车:从数据到专业图表全流程

在人工智能与数据可视化交叉领域,让模型直接生成图表往往伴随字体乱码、坐标轴密集、配色失调等高频问题。Agent Skill作为一种可复用的能力封装机制,将专业绘图流程固化为标准化操作手册,从数据特征识别、图表类型决策到代码生成与渲染校验形成完整闭环。它不再依赖临时提示词的一次性发挥,而是让AI按领域专家的思维执行任务,显著提升出图质量与稳定性。这种能力在数据分析报告、运营日报、论文插图等场景具有广泛实用价值,尤其适用于需要快速产出规范化图表的工作流。本文即从这一技术范式出发,介绍一个GitHub上获得2.5

weixin_33851429的博客 960

使用python调用zxing库生成二维码图片

(1)     安装Jpype  用python调用jar包需要安装jpype扩展,在Ubuntu上可以直接使用apt-get安装jpype扩展 $ sudo apt-get install python-jpype 关于使用Jpype调用jar包的方式,请看http://blog.youkuaiyun.com/niuyisheng/article/details/9002926  (2)

guojun07的专栏 3093

SAP PS项目计划成本与预算设计:从概念到可用性控制详解

在项目管理中,成本计划与预算管控是决定项目成本能否受控的两个核心概念。成本计划反映“预计花费”,预算是“授权上限”,两者在WBS结构上既相互关联又彼此独立。SAP PS通过计划版本管理不同口径的估算,并借助可用性控制机制对采购申请、采购订单等业务操作进行事前拦截与提示,从而实现从“事后追认”到“事前控制”的转变。理解计划成本作为预算基线、预算作为控制阀门的原理,能够帮助实施顾问和项目管理者合理设计项目财务流程。在大型工程、研发或总包项目中,明确WBS层级、预算对象和检查规则,可有效避免超支风险。围绕SAP

weixin_33146151的博客 360

android使用zxing实现自动对焦

接触到一个需求扫一维码的时候很难扫到,后来测试发现,是自动对焦问题。 zxing的自动对焦线程始终都在执行,但是硬件无法支持连续自动对焦,而只在扫描界面启动后进行一次对焦,而我们在扫码的时候不可能保证在同一距离下扫码。 解决方案: 1在 AutoFocusManager类中加入 //在这里插入代码片AutoStopTask autoStopTask; public class AutoStopTask extends AsyncTask<Object, Object, Object>{

xieyaofeng的博客 3072

手把手教你用Arduino IDE玩转ESP32-S3-wroom(附串口调试技巧)

本文详细介绍了如何在Arduino IDE环境下配置和使用ESP32-S3-WROOM模块,包括开发环境搭建、硬件连接、程序烧录及高级调试技巧。通过实战步骤和常见问题解决方案,帮助开发者快速上手这一高性能Wi-Fi/蓝牙双模模组,提升物联网开发效率。

weixin_30487201的博客 293

使用MID360在室内快速定位

在预构建的点云地图中实现实时3D全球定位。通过融合FAST-LIO的低频全局定位(约0.5~0.2Hz)和高频里程计,整个系统的计算效率很高。消除里程计的累计误差初始定位可以通过RVIZ的粗略手动估计或来自另一个传感器/算法的姿势来提供。

CTwinkle的博客 1162

在iOS中使用ZXing库

DEC 23RD, 2012 前言 ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0)。它不但支持众多的条码格式,而且有各种语言的实现版本,它支持的语言包括:Java, C++, C#, Objective-C, ActionScript和Ruby。 我上周在iOS项目开发中使用了ZXing的扫描二维码功能。在此总结

梦想实践者的技术博客 535

ThingsBoard PE专业版解决方案技术文档——温度&湿度

温湿度解决方案

weixin_67440240的博客 819
上一篇: 两次点击回退键,退出程序!
下一篇: android java 如何判断一个url地址为有效url
一往无前-千夜
博客等级 码龄10年 357粉丝 365原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值