Java調(diào)用pyzbar解析base64二維碼過程解析
一、環(huán)境配置
所有OS,建議使用python3.6;python2.7也可以,但在安裝過程中可能遇到升級pip等問題;請參考pyzbar官網(wǎng)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 zbarpip 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,";
/**
* 這種方式在源碼中成功調(diào)用,但達成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.創(chuàng)建臨時文件(由于圖片的base64字符太長,不支持直接以命令參數(shù)的形式傳遞,故將字符串寫入臨時文件,而后python程序讀取臨時文件內(nèi)容)
String tempPath = "./" + Thread.currentThread().getName();
File tempFile = new File(tempPath);
FileWriter fileWriter = new FileWriter(tempFile, false);
fileWriter.write(base64Str);
fileWriter.flush();
fileWriter.close();
//3.調(diào)用pyzbar解析base64字符串
String plainText = PyZbarUtil.executePyzbar("python", scriptPath, tempFile.getAbsolutePath());
//4.刪除臨時文件
tempFile.delete();
System.err.println("--------->" + plainText);
return plainText;
} else {
return "參數(shù)格式錯誤";
}
}
/**
* 校驗Base64值是否已規(guī)定的串開始
*
* @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 {
/**
* 腳本執(zhí)行工具類
*
* @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("腳本調(diào)用失敗");
}
} 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轉(zhuǎn)換為字節(jié)流'''
def convert_base64_to_byte_stream(base64_str):
# 1.解碼Base64字符串
img_data = base64.b64decode(base64_str)
# 2.將節(jié)碼結果轉(zhuǎn)為字節(jié)流
byte_stream = BytesIO(img_data)
return byte_stream
'''從將字節(jié)流解析二維碼'''
def parse_byte_stream_qr_code(byte_stream):
# 3.打開字節(jié)流得到圖片對象
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.調(diào)用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)
三、主要坑點
- 圖片轉(zhuǎn)base64后,得到的字符串太長,不能直接以命令參數(shù)的形式傳遞,所以必須將其寫入臨時文件,然后python腳本讀取臨時文件進行解析
- 若將python腳本放在項目中,項目打成jar包后,無法定位腳本路徑,導致執(zhí)行失敗,所以必須將腳本放在jar包外,以配置的形式將路徑傳遞給java項目
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
SpringBoot?Profiles?多環(huán)境配置及切換
大部分情況下,我們開發(fā)的產(chǎn)品應用都會根據(jù)不同的目的,所以需要支持不同的環(huán)境,本文主要介紹了SpringBoot?Profiles?多環(huán)境配置及切換,感興趣的可以了解一下2021-12-12
利用Java如何獲取Mybatis動態(tài)生成的sql接口實現(xiàn)
MyBatis 的強大特性之一便是它的動態(tài)SQL,下面這篇文章主要給大家介紹了關于利用Java如何獲取Mybatis動態(tài)生成的sql接口實現(xiàn)的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-01-01

