ZXing vs ZBar: 开源条形码SDK性能PK

很多手机app条形码应用都使用了ZXing和ZBar两个开源条形码SDK。那么从检测速度和检测率看哪个更出色呢?ZXing用Java实现,ZBar用C/C++实现,为了确保公平,这里用JNI封装ZBar,用Java写测试。

参考原文:How to Benchmark Barcode SDK Performance – ZXingvsZBar

作者:Desmond Shaw

翻译:yushulx

SDK下载

ZXing Source code

https://github.com/zxing/zxing

ZBar Source Code

https://github.com/ZBar/ZBar

ZBar Windows Installer

http://sourceforge.net/projects/zbar/files/zbar/

如何使用Java解码TIFF文件

通过Java SDK中的ImageIO,我们可以解码很多图片格式,比如JPEG,PNG,BMP。但是TIFF是不支持的。实际使用的时候,经常会用到TIFF文件读取条形码。Oracle官方提供了Java Advanced Imaging (JAI)来支持TIFF。

JAI下载

照理说Oracle的官网是应该提供JAI的下载链接的。但是很奇怪的是打开之后都是404错误。在网上搜了一圈,找到了一个可用链接:http://www.java2s.com/Code/Jar/j/Downloadjaicore113jar.htm。使用的时候需要下载jai_codec-1.1.3.jarjai_core-1.1.3.jar。这里是一个把TIFF读到int[]的例子:

File file = new File(fileName);
RenderedImage tiff = JAI.create("tiffload", fileName);
BufferedImage image = PlanarImage.wrapRenderedImage(tiff).getAsBufferedImage();
int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth();

使用ZXing读取图片中的多个条形码

ZXing中的MultiFormatReader是用来读取一个条形码的,要读取多个条形码,需要把它放到GenericMultipleBarcodeReader中:

RGBLuminanceSource source = new RGBLuminanceSource(image.getWidth(),
        image.getHeight(), pixels);
bitmap = new BinaryBitmap(new HybridBinarizer(source));
 
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.TRY_HARDER, null);
Collection<BarcodeFormat> formats = new ArrayList<>();
formats.add(BarcodeFormat.QR_CODE);
formats.add(BarcodeFormat.CODABAR);
formats.add(BarcodeFormat.CODE_39);
formats.add(BarcodeFormat.CODE_93);
formats.add(BarcodeFormat.CODE_128);
formats.add(BarcodeFormat.EAN_8);
formats.add(BarcodeFormat.EAN_13);
formats.add(BarcodeFormat.ITF);
formats.add(BarcodeFormat.UPC_A);
formats.add(BarcodeFormat.UPC_E);
formats.add(BarcodeFormat.UPC_EAN_EXTENSION);
 
hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
MultiFormatReader reader = new MultiFormatReader(); 
 
// read multi barcodes
GenericMultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(
        reader);
try {
    Result[] results = multiReader.decodeMultiple(bitmap, hints);
    System.out.println(ZXING + TIME_COST
            + ((System.nanoTime() - start) / 1000000) + MS);
    if (results != null) {
        for (Result result : results) {
            System.out.println(ZXING + TYPE + result.getBarcodeFormat() + VALUE + result.getText());
        }
    }
} catch (NotFoundException e) {
    e.printStackTrace();
    return;
}

ZBar JNI

要用JNI封装ZBar,最简单的方法就是参考自带的例子scan_image.cpp。把main函数改成JNI的接口就行了,在底层获取数据之后返回给Java层:

#include <iostream>
#include <Magick++.h>
#include <zbar.h>
#include <jni.h>
#define STR(s) #s
 
using namespace std;
using namespace zbar;
 
#ifndef DEBUG
#define DEBUG(...) printf(__VA_ARGS__)
#endif
 
extern "C" {
    JNIEXPORT jobjectArray JNICALL Java_com_dynamsoft_zbar_ZBarReader_decode(JNIEnv *env, jobject obj, jstring fileName);
}
 
JNIEXPORT jobjectArray JNICALL Java_com_dynamsoft_zbar_ZBarReader_decode(JNIEnv *env, jobject obj, jstring fileName)
{
    const char *pszFileName = env->GetStringUTFChars(fileName, 0);
 
#ifdef MAGICK_HOME
    // http://www.imagemagick.org/Magick++/
    //    under Windows it is necessary to initialize the ImageMagick
    //    library prior to using the Magick++ library
    Magick::InitializeMagick(MAGICK_HOME);
#endif
 
    // create a reader
    ImageScanner scanner;
 
    // configure the reader
    scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
 
    // obtain image data
    Magick::Image magick(pszFileName);  // read an image file
    int width = magick.columns();   // extract dimensions
    int height = magick.rows();
    Magick::Blob blob;              // extract the raw data
    magick.modifyImage();
    magick.write(&blob, "GRAY", 8);
    const void *raw = blob.data();
 
    // wrap image data
    Image image(width, height, "Y800", raw, width * height);
 
    // scan the image for barcodes
    int n = scanner.scan(image);
 
    // find java class
    jclass clsZBarResult = env->FindClass("com/dynamsoft/zbar/ZBarResult");
    // create java array
    int data_length = 0;
    for (Image::SymbolIterator symbol = image.symbol_begin();
        symbol != image.symbol_end();
        ++symbol) {
        ++data_length;
    }
 
    jobjectArray clsZBarResultArray = env->NewObjectArray(data_length, clsZBarResult, 0);
    int iIndex = 0;
 
    // extract results
    for (Image::SymbolIterator symbol = image.symbol_begin();
        symbol != image.symbol_end();
        ++symbol) {
        // do something useful with results
        //cout << "ZBR Type: " << symbol->get_type_name()
        //  << ", Value \"" << symbol->get_data() << ‘"‘ << endl;
 
        // save result to java array
        jmethodID init = env->GetMethodID(clsZBarResult, "<init>", "()V");
        jobject clsZBarResultObj = env->NewObject(clsZBarResult, init);
        jfieldID jType = env->GetFieldID(clsZBarResult, "mType", "Ljava/lang/String;");
        jfieldID jValue = env->GetFieldID(clsZBarResult, "mValue", "Ljava/lang/String;");
        env->SetObjectField(clsZBarResultObj, jType, env->NewStringUTF(symbol->get_type_name().c_str()));
        env->SetObjectField(clsZBarResultObj, jValue, env->NewStringUTF(symbol->get_data().c_str()));
        env->SetObjectArrayElement(clsZBarResultArray, iIndex, clsZBarResultObj);
        ++iIndex;       
    }
 
    // clean up
    image.set_data(NULL, 0);
 
    // release string
    env->ReleaseStringUTFChars(fileName, pszFileName);
 
    return clsZBarResultArray;
}

这里你会需要用到ImageMagick x86版本,下载地址:http://www.imagemagick.org/script/binary-releases.php

相关的Java类如下:

ZBarReader.java

package com.dynamsoft.zbar;
 
import com.dynamsoft.utils.BaseReader;
 
public class ZBarReader extends BaseReader {
 
    static {
        System.loadLibrary("zbarjni");
    }
 
    public void testZBar(String fileName) {
        long start = System.nanoTime();
        ZBarReader reader =  new ZBarReader();
        ZBarResult[] results = (ZBarResult[])reader.decode(fileName);
        System.out.println(ZBAR + TIME_COST
                + ((System.nanoTime() - start) / 1000000) + MS);
 
        if (results != null && results.length > 0) {
            mCount += 1;
            for (ZBarResult result : results) {
                System.out.println(ZBAR + TYPE + result.mType + VALUE + result.mValue);
            }
        }
    }
 
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return super.getCount();
    }
 
    public native Object[] decode(String fileName);
}

ZBarResult.java

package com.dynamsoft.zbar;
 
public class ZBarResult {
    public String mType;
    public String mValue;
}

性能PK

找一些数据集来测试。多条形码测试可以使用Dynamsoft的测试数据https://github.com/Dynamsoft/Dynamsoft-Barcode-Reader/tree/master/Images,单条形码可以使用ZXing的数据https://github.com/zxing/zxing/tree/master/core/src/test/resources。这里用ZXing的二维码数据https://github.com/zxing/zxing/tree/master/core/src/test/resources/blackbox/qrcode-1来做一个测试对比,结果如下:

F:\resources\blackbox\qrcode-1\1.png
 
ZXI Time cost: 122ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 33ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\10.png
 
ZXI Time cost: 66ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\11.png
 
ZXI Time cost: 53ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 29ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\12.png
 
ZXI Time cost: 71ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 29ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\13.png
 
ZXI Time cost: 84ms
 
ZXI Type: QR_CODE, value: http://google.com/gwt/n?u=bluenile.com
 
ZBA Time cost: 27ms
 
ZBA Type: QR-Code, value: http://google.com/gwt/n?u=bluenile.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\14.png
 
com.google.zxing.NotFoundException
 
ZBA Time cost: 32ms
 
ZBA Type: QR-Code, value: http://google.com/gwt/n?u=bluenile.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\15.png
 
ZXI Time cost: 90ms
 
ZXI Type: QR_CODE, value: http://google.com/gwt/n?u=bluenile.com
 
ZBA Time cost: 34ms
 
ZBA Type: QR-Code, value: http://google.com/gwt/n?u=bluenile.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\16.png
 
ZXI Time cost: 77ms
 
ZXI Type: QR_CODE, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
ZBA Time cost: 35ms
 
ZBA Type: QR-Code, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\17.png
 
ZXI Time cost: 82ms
 
ZXI Type: QR_CODE, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
ZBA Time cost: 32ms
 
ZBA Type: QR-Code, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\18.png
 
ZXI Time cost: 80ms
 
ZXI Type: QR_CODE, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
ZBA Time cost: 35ms
 
ZBA Type: QR-Code, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\19.png
 
ZXI Time cost: 64ms
 
ZXI Type: QR_CODE, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\2.png
 
ZXI Time cost: 61ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\20.png
 
ZXI Time cost: 55ms
 
ZXI Type: QR_CODE, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
ZBA Time cost: 30ms
 
ZBA Type: QR-Code, value: Sean Owen
 
[email protected]
 
917-364-2918
 
http://awesome-thoughts.com
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\3.png
 
ZXI Time cost: 56ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 29ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\4.png
 
ZXI Time cost: 70ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\5.png
 
ZXI Time cost: 64ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\6.png
 
ZXI Time cost: 56ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 28ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\7.png
 
ZXI Time cost: 73ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 30ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\8.png
 
ZXI Time cost: 55ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 27ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
       F:\resources\blackbox\qrcode-1\9.png
 
ZXI Time cost: 55ms
 
ZXI Type: QR_CODE, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
ZBA Time cost: 27ms
 
ZBA Type: QR-Code, value: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
 
-------------------------------------------------------------------------------------
 
ZXI passed: 19
 
ZBA passed: 20

结果发现,ZBar的二维码解码速度居然比ZXing快很多!感兴趣的同学可以去测试下别的数据。

源码

https://github.com/Dynamsoft/Dynamsoft-Barcode-Reader/tree/master/samples/Java

时间: 2024-11-06 11:42:21

ZXing vs ZBar: 开源条形码SDK性能PK的相关文章

实现扫描 一/二维码 -- ZBar开源SDK

一.下载ZBarSDK, 加入到工程中. 二.配置TARGETS和PROJECT 三.设置Link Binary With Libraries 四.  .m文件 #import "MQMainViewController.h" #import "ZBarSDK.h" @interface MQMainViewController () @end @implementation MQMainViewController - (void)viewDidLoad { [s

C#使用zxing,zbar,thoughtworkQRcode解析二维码,附源代码

最近做项目需要解析二维码图片,找了一大圈,发现没有人去整理下开源的几个库案例,花了点时间 做了zxing,zbar和thoughtworkqrcode解析二维码案例,希望大家有帮助. zxing是谷歌开源的二维码库,zbar,thoughtworkQRcode也是开源的,三者之间比较各有优劣 下面通过一个案例demo源码,来认识学习下这三者的实际解码效果, 第一次上传demo源码,献丑了 zbar解析关键代码: Image primaryImage = Image.FromFile(fileNa

Java入门到精通——基础篇String StringBuffer StringBuilder性能PK

一.概述 字符串的处理在java中我们经常要用到java提供了三个类来提供对字符串的操作,String,StringBuffer,StringBuilder String:固定长 StringBuffer:不固定长线程安全 Stringbuilder:不固定长线程不安全 二.性能PK 1.创建超大字符串. 代码: public class StringOne { public static void main(String[] args) { String str=""; String

Python zxing 库解析(条形码二维码识别)

各种扫码软件 最近要做个二维码识别的项目,查到二维码识别有好多开源的不开源的软件 http://www.oschina.net/project/tag/238/ Zbar 首先试了一下Zbar,python加载ZBar时各种报错.可能的原因是zbar的dll文件是32位的,而我系统是64位的,所以运行不了.只能自己拿源码编译一个64位的出来,对于我这种伸手党来说自己编译源码是难以接受的,所以就放弃了.后来看到文章说Zbar不能识别倾斜的条形码,而且也不能定位条形码区域. Zxing zbar不可

google开源的C++性能分析工具 - gperftools

gperftools是Google提供的一套工具,其中的一个功能是CPU profiler,用于分析程序性能,找到程序的性能瓶颈. 安装 gperftools:http://code.google.com/p/gperftools/downloads/list libunwind:http://download.savannah.gnu.org/releases/libunwind/ 64位操作系统需要安装libunwind,官方推荐版本是libunwind-0.99-beta 安装过程:./c

Yahoo 开源的 MySQL 性能分析工具(MySQL Performance Analyzer)

原文地址:https://github.com/yahoo/mysql_perf_analyzer MySQL Performance Analyzer is an open source project for MySQL performance monitoring and analysis. This repository includes two sub projects: Java web application project myperf Java web server jetty

Node、PHP、Java 和 Go 服务端 I/O 性能PK

导读 理解应用程序的输入/输出(I/O)模型,意味着其在计划处理负载与残酷的实际使用场景之间的差异.若应用程序比较小,也没有服务于很高的负载,也许它影响甚微.但随着应用程序的负载逐渐上涨,采用错误的I/O模型有可能会让你到处踩坑,伤痕累累. 正如大部分存在多种解决途径的场景一样,重点不在于哪一种途径更好,而是在于理解如何进行权衡.让我们来参观下I/O的景观,看下可以从中窃取点什么. 在这篇文章,我们将会结合Apache分别比较Node,Java,Go,和PHP,讨论这些不同的语言如何对他们的I/

热门开源网关的性能对比:Goku &gt; Kong &gt; Tyk

不多说,先展示最后的性能测试结果 我们将Goku与市场上的其他同类热门产品进行比较,使用相同的环境和条件,测试以下产品:Goku.Kong.Tyk.简单介绍下, Goku API Gateway (中文名:悟空 API 网关)是 EOLINKER 旗下自研的微服务网关,基于 Golang 开发,提供 社区版本(CE)和 企业版本(EE) ,我用来展示的是开源版本,也就是社区版本. 社区版地址:https://github.com/eolinker/goku-api-gateway 注:本次压测对

开源的Delphi性能调试工具

官网:http://dbg-spider.net/源码:https://github.com/yavfast/dbg-spider Real time profiler for Delphi applications:?  Detailed debug information (internal, TDS, MAP)?  Display information for multi-threaded applications?  Timeline diagram for process execu