Java调用pyzbar解析base64二维码过程解析

网友投稿 341 2022-11-26


Java调用pyzbar解析base64二维码过程解析

一、环境配置

所有OS,建议使用python3.6;python2.7也可以,但在安装过程中可能遇到升级pip等问题;请参考pyzbar官网https://pypi.org/project/pyzbar/

1.Ubuntu16.4

apt-get install libzbar0

pip install pyzbar

pip install Pillow

2.Centos7

yum install python-devel

yum install zbar-devel

yum install zbar

pip install Pillow

pip install pyzbar

3.Windows

pip install Pillow

pip install pyzbar

还需安装Visual C++ Redistributable Packages for Visual Studio 2013,即从微软官方下载的 vcredist_x64.exe程序

二、代码编写

java代码

UserController.java

package com.yang.springbootlucene.controller;

import lombok.Data;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.core.io.ClassPathResource;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.io.File;

import java.io.FileWriter;

import java.io.IOException;

/**

* @author:yjx

* @description:

* @date:2019/11/28 15:29

*/

@Slf4j

@RestController

@RequestMapping("/user")

public class UserController {

@Value("${pyzbar.script}")

private String scriptPath;

private static final String BASE_64_PREFIX = "data:image/png;base64,";

/**

* 这种方式在源码中成功调用,但达成jar包后,找不到脚本路径,所以脚本必须放在外面

*/

@Deprecated

private static String pyZbarScriptPath;

/* static {

ClassPathResource pathResource = new ClassPathResource("/script/my_py_zbar.py");

try {

pyZbarScriptPath = pathResource.getFile().getAbsolutePath();

} catch (IOException e) {

e.printStackTrace();

}

} */

@RequestMapping("/cameraScanPyZbar")

public Object cameraScanPyZbar(@RequestBody String base64) throws IOException {

if (this.checkBase64Head(base64)) {

//1.去掉base64字符的头部

String base64Str = this.cutHead(base64);

//2.创建临时文件(由于图片的base64字符太长,不支持直接以命令参数的形式传递,故将字符串写入临时文件,而后python程序读取临时文件内容)

String tempPath = "./" + Thread.currentThread().getName();

File tempFile = new File(tempPath);

FileWriter fileWriter = new FileWriter(tempFile, false);

fileWriter.write(base64Str);

fileWriter.flush();

fileWriter.close();

//3.调用pyzbar解析base64字符串

String plainText = PyZbarUtil.executePyzbar("python", scriptPath, tempFile.getAbsolutePath());

//4.删除临时文件

jdFlwpdBwL tempFile.delete();

System.err.println("--------->" + plainText);

return plainText;

} else {

return "参数格式错误";

}

}

/**

* 校验Base64值是否已规定的串开始

*

* @param base64

* @return

*/

private boolean checkBase64Head(String base64) {

return base64.startsWith(BASE_64_PREFIX);

}

/**

* Base64去头

*

* @param base64

* @return

*/

private String cutHead(String base64) {

return base64.replaceAll(BASE_64_PREFIX, "");

}

}

PyZbarUtil.java

package com.yang.springbootlucene.controller;

import java.io.BufferedReader;

import java.io.InputStreamReader;

public final class PyZbarUtil {

/**

* 脚本执行工具类

*

* @param lang 命令语言

* @param scriptPath 脚本绝对路劲

* @param base64Path base64文件绝对路径

* @return

*/

public static String executePyzbar(String lang, String scriptPath, String base64Path) {

String[] arguments = new String[]{lang, scriptPath, base64Path};

try {

Process process = Runtime.getRuntime().exec(arguments);

int re = process.waitFor();

if (re == 0) {

try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));) {

return in.readLine();

}

} else {

System.err.println("脚本调用失败");

}

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

python脚本my_py_zbar.py

# -*-coding:UTF-8-*-

import sys

import base64

from io import BytesIO

import pyzbar.pyzbar as pyzbar

from PIL import Image,ImageEnhance

'''将base64转换为字节流'''

def convert_base64_to_byte_stream(base64_str):

# 1.解码Base64字符串

img_data = base64.b64decode(base64_str)

# 2.将节码结果转为字节流

byte_stream = BytesIO(img_data)

return byte_stream

'''从将字节流解析二维码'''

def parse_byte_stream_qr_code(byte_stream):

# 3.打开字节流得到图片对象

img = Image.open(byte_stream)

img = ImageEnhance.Brightness(img).enhance(2.0) #增加亮度

img = ImageEnhance.Contrast(img).enhance(4.0) #增加对比度

# img = ImageEnhance.Sharpness(img).enhance(17.0) #锐利化

# img = img.convert('L') #灰度化

# img.show() # 播放图片,供测试用

# 4.调用pyzbar解析图片中的二维码

barcodes = pyzbar.decode(img)

# 5.打印解析结果

return barcodes[0].data.decode("utf-8")

def main(argv):

# print(parse_byte_stream_qr_code(convert_base64_to_byte_stream(argv[1])))

print(parse_byte_stream_qr_code(convert_base64_to_byte_stream(open(argv[1]).readline())))

if __name__ == "__main__":

main(sys.argv)

三、主要坑点

图片转base64后,得到的字符串太长,不能直接以命令参数的形式传递,所以必须将其写入临时文件,然后python脚本读取临时文件进行解析

若将python脚本放在项目中,项目打成jar包后,无法定位脚本路径,导致执行失败,所以必须将脚本放在jar包外,以配置的形式将路径传递给java项目


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java获取linux服务器上的IP操作
下一篇:springboot aspect通过@annotation进行拦截的实例代码详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~