maven导入依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
创建QRCodeUtil
package com.xjj.expense.OCR.utils;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import org.apache.commons.io.IOUtils;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.util.HashMap;
public class QRCodeUtil {
/**
* 解析二维码,返回解析内容
*/
public static String decodeQrCode(File file) throws Exception {
// BufferedImage内存中的图片
BufferedImage image = ImageIO.read(file);
//觉得解析速度太慢,可对图片进行裁剪(裁剪出二维码就行了)
// image = cropImage(image, image.getWidth()/23 , image.getHeight()/87,image.getWidth()/6 ,image.getHeight()/4 );
//对图片进行等比2倍放大
// image = zoomImage(image,image.getWidth(),image.getHeight());
//HybridBinarizer二维码识别度较精确,解析速度较慢
BinaryBitmap binaryBitmap = new BinaryBitmap(
new HybridBinarizer(new BufferedImageLuminanceSource(image)));
//GlobalHistogramBinarizer二维码识别度不够精确,解析速度较快
/* BinaryBitmap binaryBitmap = new BinaryBitmap(
new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
*/
// 定义二维码的参数:
HashMap<DecodeHintType, Object> hints = new HashMap<>();
// 定义字符集
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
// 解密
Result result = new MultiFormatReader().decode(binaryBitmap, hints);
if (result == null) {
return "";
}
return result.getText();
}
/**
* 裁剪图片方法
*
* @param bufferedImage 图像源
* @param startX 裁剪开始x坐标
* @param startY 裁剪开始y坐标
* @param endX 裁剪结束x坐标
* @param endY 裁剪结束y坐标
* @return
*/
public static BufferedImage cropImage(BufferedImage bufferedImage, int startX, int startY, int endX, int endY) throws Exception{
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if (startX == -1) {
startX = 0;
}
if (startY == -1) {
startY = 0;
}
if (endX == -1) {
endX = width - 1;
}
if (endY == -1) {
endY = height - 1;
}
BufferedImage result = new BufferedImage(endX - startX, endY - startY, 4);
for (int x = startX; x < endX; ++x) {
for (int y = startY; y < endY; ++y) {
int rgb = bufferedImage.getRGB(x, y);
result.setRGB(x - startX, y - startY, rgb);
}
}
//bufferedimage 转换成 inputstream
/* ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(result, "png", imOut);
InputStream inputStream = new ByteArrayInputStream(bs.toByteArray());
OutputStream outStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\99.png");
IOUtils.copy(inputStream, outStream);
inputStream.close();
outStream.close();*/
return result;
}
/*
* 图片缩放,w,h为缩放的目标宽度和高度
* src为源文件目录,dest为缩放后保存目录
*/
public static BufferedImage zoomImage(BufferedImage bufImg,int w,int h) throws Exception {
double wr=0,hr=0;
String dest = "C:\\Users\\Administrator\\Desktop\\99.jpg";
File destFile = new File(dest);
BufferedImage Itemp = (BufferedImage) bufImg.getScaledInstance(w, h, bufImg.SCALE_SMOOTH);//设置缩放目标图片模板
wr=w*2.0/bufImg.getWidth(); //获取缩放比例
hr=h*2.0 / bufImg.getHeight();
AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
Itemp = ato.filter(bufImg, null);
//写入缩减后的图片
/* try {
ImageIO.write((BufferedImage) Itemp,dest.substring(dest.lastIndexOf(".")+1), destFile);
} catch (Exception ex) {
ex.printStackTrace();
}*/
return Itemp;
}
public static void main(String[] args) throws Exception {
String filePath = "C:\\Users\\Administrator\\Desktop\\aa.jpg";
String reText = decodeQrCode(new File(filePath));
// 解码
String[] result = reText.split(",");
String type = result[1];
String fp = "增值税电子普通发票";
if(type.equals("04")){
fp = "增值税普通发票";
}else if(type.equals("01")){
fp = "增值税专用发票";
}
String fpdm = result[2];
String fphm = result[3];
String hjje = result[4];
String kprq = result[5];
String fpjym = result[6];
System.out.println(reText);
System.out.println(fp);
System.out.println("发票代码 "+fpdm);
System.out.println("发票号码 "+fphm);
System.out.println("合计金额 "+hjje+"(不含税)");
System.out.println("开票日期 "+kprq);
System.out.println("发票校验码 "+fpjym);
}
}
解析结果
解析结果表示的含义
01,10,046001900111,15448190,1073.46,20200108,76981080480389748902,28C1,
1.第一个属性值[01]:暂不清楚
2.第二个属性值[10]:代表发票种类代码,有三个属性值
10:增值税电子普通发票;
04:增值税普通发票;
01:增值税专用发票;
3.第三个属性值[046001900111]:表示发票代码
4.第四个属性值[1544819]:表示发票号码
5.第五个属性值[1073.46]:表示金额
6.第六个属性值[20200108]:表示开票日期
7.第七个属性值[76981080480389748902]:表示发票校验码,(增值税专用发票是没有发票校验码的,没有则为空字符串)
8.第八个属性值[28C1]:表示发票的随机码