Python zxing 庫解析(條形碼二維碼識別)


各種掃碼軟件

最近要做個二維碼識別的項目,查到二維碼識別有好多開源的不開源的軟件

http://www.oschina.net/project/tag/238/

 

Zbar

首先試了一下Zbar,python加載ZBar時各種報錯。可能的原因是zbar的dll文件是32位的,而我系統是64位的,所以運行不了。只能自己拿源碼編譯一個64位的出來,對於我這種伸手黨來說自己編譯源碼是難以接受的,所以就放棄了。后來看到文章說Zbar不能識別傾斜的條形碼,而且也不能定位條形碼區域。

Zxing

zbar不可行,就試一下zxing吧。很容易的找到了zxing在github上的頁面。

https://github.com/zxing/zxing/

然后發現zxing還有python版本:

image

一陣激動啊,點進去(https://github.com/oostendo/python-zxing),發現作者對這個python包的描述是:A quick and dirty wrapper for the ZXing barcode library.(一個快速且簡陋的zxing外殼)

image

把zxing文件夾還有其他幾個文件都下載下來,下面開始折騰這個簡陋的包。

建立Python Zxing項目

在Eclipse里新建一個PyDev項目,把zxing文件夾拷貝進去。

image

由於包含__init__.py這個文件,文件夾被自動識別為一個包。

tests.py是一個調用zxing識別條形碼的例程。主函數中調用了一個test_codereader()函數來識別當前目錄下一張圖片 sample.png 中的條形碼。

image

而test_codereader()則調用了這個為python開發的zxing包中decode()函數

zx = BarCodeReader()

barcode = zx.decode(testimage)

順藤摸瓜,打開__init__.py,里面有BarCodeReader()這個類的實現代碼。

Python調用jar包

在decode函數中,用subprocess包中的Popen實現了調用jar包的操作,類似於VB,VC中的管道通訊。

(stdout, stderr) = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True).communicate()

上面這句就是調用jar包的核心代碼,cmd是發給jar包的命令。cmd的類型是list,每個元素是一個參數,最終輸入給jar的命令形式如下。

['java', '-cp', '.;javase.jar;core.jar;jcommander-1.48.jar', 'com.google.zxing.client.j2se.CommandLineRunner', 'sample.png']

subprocess的使用方法網上有好多教程,這里主要的問題出在了調用jar包的命令本身。

出現的問題及解決方法

既然是例程,拿到手當然直接運行,卻卡在了subprocess.Popen()這里,報的錯誤是無法加載java主類。

1、錯誤: 找不到或無法加載主類 com.google.zxing.client.j2se.CommandLineRunnercmd

於是把cmd命令輸出了一下,這句命令是 java   –cp   包路徑/jar報名.jar    java類名。

首先發現的問題是我的目錄里沒有程序里指定的這兩個jar包(javase.jar;core.jar),而且路徑也不對。於是從網上搜到這兩個包的地址下載下來(當然也可以下載zxing的源碼手動編譯)。

關於如何編譯zxing的文章: http://blog.sina.com.cn/s/blog_76adb0160102uxqb.html

下載zxing的兩個jar包的文章:http://blog.csdn.net/rongbo_j/article/details/47055795

“zxing的jar包我們可以從maven資源庫中獲取,打開maven資源庫http://www.mvnrepository.com/,搜索zxing即可”

下載完jar包,把名字改為core.jar和javase.jar(為了跟代碼配合去掉了后面一串數字),拷貝到剛才項目的中的zxing文件夾中即可。

image

注意到原版程序中還給jar包加了目錄 libs = ["javase/javase.jar", "core/core.jar"]

我們需要把這句改成libs = ["javase.jar", "core.jar"],就是這么簡單粗暴。

再試一下,還是不行,輸出的cmd為:

['java', '-cp', '../javase.jar;../core.jar', 'com.google.zxing.client.j2se.CommandLineRunner', 'sample.png']

中jar包的路徑變成了../javase.jar;../core.jar,這斜杠和點一加,目錄就不對了。

於是找到給路徑加斜杠的那句代碼:
libraries = [self.location + "/" + l for l in self.libs]

把斜杠給刪掉,改成

libraries = [ l for l in self.libs]

這樣就去掉了路徑中的雙點和斜杠,再次運行,迎接新的問題。

2、NoClassDefFoundError: com/beust/jcommander/JCommander

具體信息如下:

Exception in thread "main" java.lang.NoClassDefFoundError: com/beust/jcommander/JCommander
    at com.google.zxing.client.j2se.CommandLineRunner.main(CommandLineRunner.java:52)
Caused by: java.lang.ClassNotFoundException: com.beust.jcommander.JCommander
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

找不到JCommander類,雖然還是有問題,但主類總算找到了。。。

查了一下,原來JCommander是一個Java的命令行解析類,並不包含在zxing的jar包里面。需要單獨下載並放到項目目錄下。

參考鏈接:http://stackoverflow.com/questions/30435688/getting-java-lang-noclassdeffounderror-com-beust-jcommander-parameterexception

鏈接里5樓的回復比較給力,因為給出了JCommander的下載地址:http://central.maven.org/maven2/com/beust/jcommander/1.48/jcommander-1.48.jar

把jar包放到zxing文件里,並在lib中添加這個包,即:

libs = ["javase.jar", "core.jar","jcommander-1.48.jar"]

image

現在的cmd命令變成了:

['java', '-cp', 'javase.jar;core.jar;jcommander-1.48.jar', 'com.google.zxing.client.j2se.CommandLineRunner', 'sample.png']

程序運行成功,但是條形碼的信息並沒有輸出,我們可以在調試的時候手動輸出一下。返回的信息存儲在file_results中,輸出一下即可。

image
可以看出這個二維碼對應的是一個網址,大家可以用手機的掃一掃驗證一下對不對。

條形碼也可以

找了個條形碼的圖片,放到目錄下試了試,也可以識別。

sample1

image

本文源碼

本文項目的源碼(包含那幾個jar文件)已上傳到CSDN:

http://download.csdn.net/detail/sheep7777777/9733896


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM