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.删除临时文件
      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项目

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅析Java 常用的 4 种加密方式(MD5+Base64+SHA+BCrypt)

    一.工具类  md5加密工具类  public class MD5Utils { private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b",&qu

  • Java实现文件和base64流的相互转换功能示例

    本文实例讲述了Java实现文件和base64流的相互转换功能.分享给大家供大家参考,具体如下: import java.io.FileInputStream; import java.io.FileOutputStream; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * 文件与base64的互相转换操作 */ public class testFile { public static void main(S

  • java实现图片转base64字符串 java实现base64字符串转图片

    java 图片转base64字符串.base64字符串转图片,具体内容如下 1. 图片转base64字符串: /** * base64编码字符串转换为图片 * @param imgStr base64编码字符串 * @param path 图片路径 * @return */ public static boolean base64StrToImage(String imgStr, String path) { if (imgStr == null) return false; BASE64Dec

  • 基于Java实现文件和base64字符串转换

    这篇文章主要介绍了基于Java实现文件和base64字符串转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 项目中遇到需要将图片转成base64编码的字符串的需求,但是,考虑到扩展性,写了一个可以转换任务类型文件的方法.需要引入的包: <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId

  • 详解Java如何进行Base64的编码(Encode)与解码(Decode)

    关于base64编码Encode和Decode编码的几种方式 Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便.在实际应用上,Base64除了能将Binary资料可视化之外,也常用来表示字串加密过后的内容.如果要使用Java 程式语言来实作Base64的编码与解码功能,可以参考本篇文章的作法. 早期作法 早期在Java上做Base64的编码与解码,会使用到JDK里sun.misc套件下的BASE64Enco

  • Java实现base64图片编码数据转换为本地图片的方法

    本文实例讲述了Java实现base64图片编码数据转换为本地图片的方法.分享给大家供大家参考,具体如下: 项目中用到的把base64图片数据转为本地图片的函数 /** * 替换html中的base64图片数据为实际图片 * @param html * @param fileRoot 本地路径 * @param serRoot 服务器路径 * @return */ public static String replaceBase64Image(String html,String fileRoot

  • java将图片转为base64返回给前端

    本文实例为大家分享了java将图片转为base64返回给前端的具体代码,供大家参考,具体内容如下 一.controller端代码 @RequestMapping(value = "/captcha") public void imagecode(HttpServletRequest request, HttpServletResponse response) throws Exception { JSONObject object = new JSONObject(); Captcha

  • Java处理图片实现base64编码转换

    前言 环境:使用这个代码前:请确保你的JDk是JAVA8及其以上 开发测试地址:http://imgbase64.duoshitong.com/ 可以查看是否执行成功 注意事项 一般插件返回的base64编码的字符串都是有一个前缀的."data:image/jpeg;base64," 解码之前这个得去掉. Code MainTest /** * 示例 * @throws UnsupportedEncodingException * @throws FileNotFoundExcepti

  • 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 z

  • PHP基于phpqrcode类库生成二维码过程解析

    phpqrcode类库官网下载地址: https://sourceforge.net/projects/phpqrcode/ 1.我们先看看php是怎么生成二维码的 1.首先我们先下载一下 phpqrcode 类库. 2.下载完后解压我们会发现 phpqrcode文件夹 里面有一堆的文件,但是我们只需要找到 phpqrcode.php文件复制, 跟 index.php 文件放在一起即可,而 index.php 就是你生成二维码的php代码. 3.接下来就是代码环节了,复制以下代码黏贴到php文件

  • Java实现的生成二维码和解析二维码URL操作示例

    本文实例讲述了Java实现的生成二维码和解析二维码URL操作.分享给大家供大家参考,具体如下: 二维码依赖jar包,zxing <!-- 二维码依赖 start --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.0.0</version> </dependency&

  • 如何用Python生成二维码、解析二维码

    楔子 二维码在我们的生活中可以说是必不可少的,不单单是手机支付.其它很多地方也都需要扫描二维码.那么下面我们就来看看如何使用python来生成二维码.以及识别二维码. 关于二维码,我们来说一下它的结构.当然关于二维码的结构其实不是太重要,这里只是提一下,没兴趣可以不用看. 从图中我们可以看出二维码结构整体划分为功能图形和编码区两大部分,功能图形又细分为:空白区.位置探测图形.位置探测图形分隔符.定位图形.校正图形,而编码区细分为:格式信息.版本信息.数据和纠错码字,来简单了解一下每一部分的功能:

  • java实现电脑端扫描二维码

    本文实例为大家分享了java实现电脑端扫描二维码的具体代码,供大家参考,具体内容如下 说明:js调去电脑摄像头拍照,然后获取图片base64位编码,再将base64为编码转为bolb,通过定时异步上传到后台,在后台对图片文件进行解码,返回解码结果到页面,然后页面重新加载结果(url) 第一种方式引入js <script type="text/javascript" src="${basePath}js/jquery-1.9.min.js"></sc

  • Java Spring boot实现生成二维码

    目录 一.引入springboot依赖: 二.工具类代码: 三.调用工具类生成二维码 1.将链接生成二维码图片并保存到指定路径 2.将链接生成二维码直接显示在页面 3.将以get请求传参链接生成二维码 总结 一.引入spring boot依赖: <!--引入生成二维码的依赖--> <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <dependency> <groupId>co

  • java微信扫描公众号二维码实现登陆功能

    本文实例为大家分享了java微信扫描公众号二维码实现登陆的具体代码,供大家参考,具体内容如下 前提条件: 1.微信公众平台为服务号, 2.服务号实现了账号绑定功能,即将open_id 与业务系统中的用户名有对应关系 具体实现原理: 1.用户访问业务系统登陆页时,调用二维码接口,获得二维码的ticketid,同时将sessionid,ticketid和二维码的seceneid保存 2.返回登陆页时,根据ticketid获得微信二维码 3.页面通过ajax发送请求,判断是否已经扫描成功. 4.公众平

  • Java生成中间logo的二维码的示例代码

    最近有负责微信开发,对于微信开发的项目,肯定少不了二维码啦,正好有个这样的需求,这对不同的商品生成一个二维码,扫码即刻下单.博主就弄了一个二维码生成的工具类. 弄出来之后,产品经理又说了,中间放上公司的logo是不是好一点?加上吧, 加上公司logo之后,产品经理想了想,每个商品都有个二维码,销售人员有很多个商品二维码,群发给用户,在qq群上,微信群上,怎么知道哪个二维码对应哪个商品的呢?于是决定要加上商品名称.最后商品二维码就成了下面这个模样了(当然啦,这里面的logo并不是博主现职公司的).

  • java使用jar包生成二维码的示例代码

    使用java进行二维码的生成与读取使用到了谷歌的zxing.jar 第一步 导入,maven依赖或者下载指定jar包 <!-- https://mvnrepository.com/artifact/com.google.zxing/javase --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version

  • Java生成读取条形码和二维码的简单示例

    条形码 将宽度不等的多个黑条和白条,按照一定的编码规则排序,用以表达一组信息的图像标识符 通常代表一串数字 / 字母,每一位有特殊含义 一般数据容量30个数字 / 字母 二维码 用某种特定几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息 比一维条形码能存储更多信息,表示更多数据类型 能够存储数字 / 字母 / 汉字 / 图片等信息 可存储几百到几十KB字符 Zxing Zxing主要是Google出品的,用于识别一维码和二维码的第三方库 主要类: BitMatrix位图

随机推荐