[Python]在Windows系统中使用ZXing模块实现二维码、条形码读码,pythonzxing,??需要实现Pyth
[Python]在Windows系统中使用ZXing模块实现二维码、条形码读码,pythonzxing,??需要实现Pyth
??需要实现Python读取图片中二维码、条形码信息。前段时间研究使用zbarlight模块,费了很大功夫安装调试好,但是发现有些图片读取不正确,而且如果图片中二维码倾斜,就读取不了,不能满足要求。昨天琢磨着试一试ZXing,下载ZXing模块安装后,却一直报错。打开模块源码仔细分析,原来该模块是通过调用java程序,使用ZXing的java库来实现的,通过分析命令行输出得到解码结果。忙活了一天多,各种测试、查资料,终于解决了问题。调试过程非常艰辛,现将做法整理如下(Windows 10系统):
?一、 因为需要调用java程序,必须安装jdk。
下载java安装程序,根据提示一步步安装。下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html。
设置环境变量。添加JAVA_HOME环境变量,其值设置为jdk安装目录。将java运行程序所在目录(%JAVA_HOME%\bin)添加到PATH。
在命令行输入java -version并执行,如果没有问题则说明安装成功。?二、下载ZXing的jar库文件,以及所需java库文件。
下载ZXing Core和ZXing Java SE Extensions库文件。登录网址http://www.mvnrepository.com,在搜索栏中输入"zxing"并查找,就能找到这两个库,下载库文件并将其分别改名为core.jar和javase.jar。
下载 JCommander库文件。在测试中,安装了上面两个库以后,仍然报错,错误信息中提示JCommander模块找不到,后来下载了这个库文件,经过多番调试,终于成功。登录网址http://www.mvnrepository.com,在搜索栏中输入"jcommander"并查找,就能找到这个库,下载库文件并将其改名为jcommander.jar。
创建一个目录,并将以上三个jar文件复制到其中。这个目录可以创建在java安装目录下。我是在java目录下建了一个名为jar的文件夹,将上面三个文件复制到里面。
设置环境变量。添加ZXING_JAR_PATH环境变量,将其值设为上面创建的那个文件夹的绝对路径,我的路径是“d:\java\jar”。
?三、在ZXing源代码基础上进行修改,实现二维码、条形码解码功能;增加了两个函数,解决了不支持图片Windows格式绝对路径的问题。
#导入模块import subprocess, re, osclass BarCodeReader(): """ 解码器类,调用java执行ZXing库命令实现解码,通过分析输出获得结果。 此模块在ZXing源码基础上修改,改动较大。 """ #ZXing库路径 location = "" #ZXing库 libs = ["javase.jar", "core.jar", "jcommander.jar"] #subprocess.Popen参数 args = ["java", "-cp", "LIBS", "com.google.zxing.client.j2se.CommandLineRunner"] def __init__(self, loc=None): """ 初始化函数,参数loc设置ZXing库所在位置 """ #如果loc为空或者不是字符串对象,读取环境变量ZXING_JAR_PATH的值(没找到就设为空字符串) if not loc or not isinstance(loc,str): loc = os.environ.get("ZXING_JAR_PATH", "") #如果loc不为空,在末尾加上‘\‘,否则设为默认值(即在当前目录的zxing子目录下) if loc: loc = loc.rstrip("\\") + "\\" else: loc = "zxing\\" #设置location self.location = loc def decode(self, files, try_harder = False, qr_only = False): """ 解码方法,参数files可以是一个文件名(字符串),也可以是一个文件名列表。 """ #根据try_harder和qr_only参数设置,添加相应选项 if try_harder: self.args.append("--try_harder") if qr_only: self.args.append("--possibleFormats=QR_CODE") #为ZXing库加上路径 libraries = [self.location + lib for lib in self.libs] #生成命令列表 cmd = [ c if c != "LIBS" else os.pathsep.join(libraries) for c in self.args ] #单文件标志设为False SINGLE_FILE = False #如果files不是列表,将文件files添加到cmd列表,单文件标志设为True if not isinstance(files, list): cmd.append(files) SINGLE_FILE = True #否则,将文件列表files添加到cmd列表 else: cmd += files #利用subprocess.Popen函数执行命令 (stdout, stderr) = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True).communicate() #初始化编码列表 codes = [] #分析输出内容 file_results = stdout.split("\nfile:") for result in file_results: lines = result.split("\n") if re.search("No barcode found", lines[0]): codes.append(None) else: codes.append(BarCode(result)) #如果是单文件,返回第一个BarCode对象;否则,返回BarCode对象列表 if SINGLE_FILE: return codes[0] else: return codesclass BarCode: """ BarCode信息类,包含解码所得各项信息。 此模块基本使用了ZXing源码,为方便使用,添加了几个属性。 """ format = "" points = [] data = "" raw = "" def __init__(self, zxing_output): lines = zxing_output.split("\n") raw_block = False parsed_block = False point_block = False self.points = [] for l in lines: m = re.search("format:\s([^,]+)", l) if not raw_block and not parsed_block and not point_block and m: self.format = m.group(1) continue if not raw_block and not parsed_block and not point_block and l == "Raw result:": raw_block = True continue if raw_block and l != "Parsed result:": self.raw += l + "\n" continue if raw_block and l == "Parsed result:": raw_block = False parsed_block = True continue if parsed_block and not re.match("Found\s\d\sresult\spoints", l): self.data += l + "\n" continue if parsed_block and re.match("Found\s\d\sresult\spoints", l): parsed_block = False point_block = True continue if point_block: m = re.search("Point\s(\d+):\s\(([\d\.]+),([\d\.]+)\)", l) if (m): self.points.append((float(m.group(2)), float(m.group(3)))) #去除多余换行符 self.raw = self.raw.rstrip("\n") self.data = self.data.rstrip("\n") @property def Format(self): """ 返回编码格式 """ return self.format @property def Data(self): """ 返回编码数据 """ return self.data @property def Points(self): """ 返回坐标点 """ return self.points @property def RawData(self): """ 返回解码所得原始数据 """ return self.rawdef GetCodeString(filename): """ 解码函数,只处理单个文件,参数为文件名(含路径)。 返回编码字符串,如果未能成功解码或未找到条码,返回空字符串。 """ #将‘\‘替换成‘/‘ filename = filename.replace("\\", "/") #如果带有盘符(绝对路径),前面加上‘file:/‘ if re.match(‘^[A-Za-z]:‘, filename): filename = "file:/" + filename #创建解码器对象 zxcode = BarCodeReader() #解码,并将结果保存到barcode barcode = zxcode.decode(filename) #如果结果为None,返回空串,否则返回编码字符串 if barcode is None: return "" else: return barcode.Datadef GetCodeObject(filename): """ 解码函数,只处理单个文件,参数为文件名(含路径)。 返回编码对象,其属性如下: Data,编码信息; Format,编码类别; Points,坐标点; RawData,未处理的编码信息。 如果未能成功解码或未找到条码,返回None """ #将‘\‘替换成‘/‘ filename = filename.replace("\\", "/") #如果带有盘符(绝对路径),前面加上‘file:/‘ if re.match(‘^[A-Za-z]:‘, filename): filename = "file:/" + filename #创建解码器对象 zxcode = BarCodeReader() #解码,并将结果保存到barcode barcode = zxcode.decode(filename) #返回结果 return barcode
?四、测试。将上述代码保存到zxing.py文件中,编辑测试代码如下:
from zxing import GetCodeString,GetCodeObjectresult = GetCodeString("d:\\barcode.png")print(result)result = GetCodeObject("d:\\qr.png")if result: print("Format:", result.Format) print("Data: ", result.Data) print("Points:") for point in result.Points: print(point)
?五、可以将以上面的代码安装到Python库(注册为zxing模块)。
下载python-zxing模块。下载地址为https://github.com/oostendo/python-zxing。
解压缩到python-zxing文件夹。
将python-zxing\zxing文件夹内__init__.py文件的内容替换成第三步的代码。
在python-zxing文件夹下打开命令行,运行python setup.py install即可。
同样可以使用第四步的代码进行测试。
[Python]在Windows系统中使用ZXing模块实现二维码、条形码读码
相关内容
- Python 爬虫实例(7)—— 爬取 新浪军事新闻,python新浪
- python异步加协程获取比特币市场信息,python比特,目标
- 毕业设计 python opencv实现车牌识别 界面,pythonopencv,主要
- 练习题|python常用模块,练习题python模块,re模块练习1.验
- python错误 invalid command 'bdist_wheel' &
- python字符串替换之re.sub(),pythonre.sub,re.sub(pat
- python-生僻字转拼音,python-生僻字拼音, 1 from t
- python3与python2编码导致 hmac.new/base64.b64encode('val
- Python标准库(3.x): itertools库扫盲,pythonitertools,itertools
- mac上Python安装和修改Python默认路径遇到的问题,macpyt
评论关闭