JAVA中生成、解析二维码图片的方法
JAVA中生成、解析二维码的方法并不复杂,使用google的zxing包就可以实现。下面的方法包含了生成二维码、在中间附加logo、添加文字功能,并有解析二维码的方法。
一、下载zxing的架包,并导入项目中,如下:

最主要的包都在com.google.zxing.core下。如果是maven项目,maven依赖如下:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
二、二维码生成,附上代码例子,如下:
public class TestQRcode {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int margin = 0;
private static final int LogoPart = 4;
/**
* 生成二维码矩阵信息
* @param content 二维码图片内容
* @param width 二维码图片宽度
* @param height 二维码图片高度
*/
public static BitMatrix setBitMatrix(String content, int width, int height){
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,防止中文乱码
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级
hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小
BitMatrix bitMatrix = null;
try {
bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
} catch (WriterException e) {
e.printStackTrace();
}
return bitMatrix;
}
/**
* 将二维码图片输出
* @param matrix 二维码矩阵信息
* @param format 图片格式
* @param outStream 输出流
* @param logoPath logo图片路径
*/
public static void writeToFile(BitMatrix matrix, String format, OutputStream outStream, String logoPath) throws IOException {
BufferedImage image = toBufferedImage(matrix);
// 加入LOGO水印效果
if (StringUtils.isNotBlank(logoPath)) {
image = addLogo(image, logoPath);
}
ImageIO.write(image, format, outStream);
}
/**
* 生成二维码图片
* @param matrix 二维码矩阵信息
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
/**
* 在二维码图片中添加logo图片
* @param image 二维码图片
* @param logoPath logo图片路径
*/
public static BufferedImage addLogo(BufferedImage image, String logoPath) throws IOException {
Graphics2D g = image.createGraphics();
BufferedImage logoImage = ImageIO.read(new File(logoPath));
// 计算logo图片大小,可适应长方形图片,根据较短边生成正方形
int width = image.getWidth() < image.getHeight() ? image.getWidth() / LogoPart : image.getHeight() / LogoPart;
int height = width;
// 计算logo图片放置位置
int x = (image.getWidth() - width) / 2;
int y = (image.getHeight() - height) / 2;
// 在二维码图片上绘制logo图片
g.drawImage(logoImage, x, y, width, height, null);
// 绘制logo边框,可选
// g.drawRoundRect(x, y, logoImage.getWidth(), logoImage.getHeight(), 10, 10);
g.setStroke(new BasicStroke(2)); // 画笔粗细
g.setColor(Color.WHITE); // 边框颜色
g.drawRect(x, y, width, height); // 矩形边框
logoImage.flush();
g.dispose();
return image;
}
/**
* 为图片添加文字
* @param pressText 文字
* @param newImage 带文字的图片
* @param targetImage 需要添加文字的图片
* @param fontStyle 字体风格
* @param color 字体颜色
* @param fontSize 字体大小
* @param width 图片宽度
* @param height 图片高度
*/
public static void pressText(String pressText, String newImage, String targetImage, int fontStyle, Color color, int fontSize, int width, int height) {
// 计算文字开始的位置
// x开始的位置:(图片宽度-字体大小*字的个数)/2
int startX = (width-(fontSize*pressText.length()))/2;
// y开始的位置:图片高度-(图片高度-图片宽度)/2
int startY = height-(height-width)/2 + fontSize;
try {
File file = new File(targetImage);
BufferedImage src = ImageIO.read(file);
int imageW = src.getWidth(null);
int imageH = src.getHeight(null);
BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, imageW, imageH, null);
g.setColor(color);
g.setFont(new Font(null, fontStyle, fontSize));
g.drawString(pressText, startX, startY);
g.dispose();
FileOutputStream out = new FileOutputStream(newImage);
ImageIO.write(image, "png", out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String content = "http://www.baidu.com";
String logoPath = "C:/logo.png";
String format = "jpg";
int width = 180;
int height = 220;
BitMatrix bitMatrix = setBitMatrix(content, width, height);
// 可通过输出流输出到页面,也可直接保存到文件
OutputStream outStream = null;
String path = "c:/qr"+new Date().getTime()+".png";
try {
outStream = new FileOutputStream(new File(path));
writeToFile(bitMatrix, format, outStream, logoPath);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
// 添加文字效果
int fontSize = 12; // 字体大小
int fontStyle = 1; // 字体风格
String text = "测试二维码";
String withTextPath = "c:/text"+new Date().getTime()+".png";
pressText(text, withTextPath, path, fontStyle, Color.BLUE, fontSize, width, height);
}
}
三、生成效果如下:

代码注释比较详细,就不多解释啦,大家可以根据自己的需求进行调整。
PS:
1、如果想生成带文字的二维码,记得要用长方形图片,为文字预留空间。
2、要生成带logo的二维码要注意遮挡率的问题,setBitMatrix()方法中ErrorCorrectionLevel.H这个纠错等级参数决定了二维码可被遮挡率。对应如下:
| L水平 | 7%的字码可被修正 |
| M水平 | 15%的字码可被修正 |
| Q水平 | 25%的字码可被修正 |
| H水平 | 30%的字码可被修正 |
四、二维码解析,附上代码例子,如下:
/**
* 解析二维码图片
* @param filePath 图片路径
*/
public static String decodeQR(String filePath) {
if ("".equalsIgnoreCase(filePath) && filePath.length() == 0) {
return "二维码图片不存在!";
}
String content = "";
EnumMap<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,防止中文乱码
try {
BufferedImage image = ImageIO.read(new FileInputStream(filePath));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
MultiFormatReader reader = new MultiFormatReader();
Result result = reader.decode(binaryBitmap, hints);
content = result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
可以从二维码图片中解析出具体的内容。
JAVA中生成、解析二维码图片的方法的更多相关文章
- Java使用ZXing生成/解析二维码图片
ZXing是一种开源的多格式1D/2D条形码图像处理库,在Java中的实现.重点是在手机上使用内置摄像头来扫描和解码设备上的条码,而不与服务器通信.然而,该项目也可以用于对桌面和服务器上的条形码进行编 ...
- ZXing 生成、解析二维码图片的小示例
概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...
- qrcode.js的识别解析二维码图片和生成二维码图片
qrcode只通过前端就能生成二维码和解析二维码图片, 首先要引入文件qrcode.js,下载地址为:http://static.runoob.com/download/qrcodejs-04f46c ...
- 使用zxing生成解析二维码
1. 前言 随着移动互联网的发展,我们经常在火车票.汽车票.快餐店.电影院.团购网站以及移动支付等各个场景下见到二维码的应用,可见二维码以经渗透到人们生活的各个方面.条码.二维码以及RFID被人们应用 ...
- 用CIFilter生成QRCode二维码图片
用CIFilter生成QRCode二维码图片 CIFilter不仅仅可以用来做滤镜,它还可以用来生成二维码. CIFilterEffect.h + CIFilterEffect.m // // CIF ...
- java生成/解析二维码
package a; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import ...
- JAVA生成解析二维码
package com.mohe.twocode; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.B ...
- pbfunc外部函数扩展应用-直接在Datawindow中生成QR二维码,非图片方式
利用pbfunc外部函数在Datawindow中直接生成QR二维码,非图片方式.需要注意以下面几点: Datawindow的DataObject的单位必须为像素(Pixels). Datawindow ...
- .net如何解析二维码图片
二维码现在越来越流行,可以使用手机上或其它移动终端上的二维码扫描器软件对着二维码一扫,就可以得到相关信息.在互联网站上,可以找到很多二维码的工具,甚至还有不少在线生成.解析二维码的网站.在业务系统当中 ...
随机推荐
- 5.For loops
for 循环语句 在需要重复执行代码的时候,for循环常常被用到.我们可以让一行代码执行10次: for i in range(1,11): print(i) 最后一个数字11是不包含在内 ...
- 搬个小板凳,我们扯扯Docker的前生
一.新瓶装旧酒 首先我们需要知道,Docker是一个"箩筐": 1.存储:Device Mapper.BtrFS.AUFS 2.名字空间:UTS.IPC.Mount.PID.Net ...
- 云服务器 远程mysql 无法连接
问题:mysql不管是用免安装版的,还是用直接安装的,还是用phpStudy直接发布的mysql服务.都只能用localhost登录,不能用服务器的ip进行远程访问 遇到这个问题.按照网上大家介绍的方 ...
- 先从_proto_下手理解原型--原型学习(一)
给自己关于原型的学习分了一个大类,主要跟踪学习js的原型.--来自<JavaScript面向对象编程指南>的笔记,这本书难度适中,适合我们这种js基础不牢的人学习. 原型这块有两个属性:p ...
- Java的参数传递是值传递还是引用传递
当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个对象实例作为一个参数被传递到方法中 ...
- top命令参数解析
PID 进程ID USER 进程所有者的用户名 PR 任务优先级 NI nice值.数值越小表示优先级越高,数值越大表示优先越低. VIRT 进程使用的虚拟内存总量,单位kb.VIRT=SWAP+RE ...
- deeplearning.ai 卷积神经网络 Week 2 深度卷积网络:实例研究 听课笔记
1. Case study:学习经典网络的原因是它们可以被迁移到其他任务中. 1.1)几种经典的网络: a)LeNet-5(LeCun et al., 1998. Gradient-based lea ...
- deeplearning.ai 人工智能行业大师访谈 Andrej Karpathy 听课笔记
1. 本科的时候在多伦多大学上Geoffrey Hinton的课,在MNIST数字数据集上训练受限玻尔兹曼机,觉得很有趣.后来在UBC读硕士,上了另一门机器学习的课,那是他第一次深入了解神经网络的相关 ...
- COGS 68. [NOIP2005] 采药【01背包复习】
68. [NOIP2005] 采药 ★ 输入文件:medic.in 输出文件:medic.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 辰辰是个天资聪颖的孩 ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1018 用线段树维护区间连通性,对于每一个区间记录6个域表示(左上,左下)(左上,右上)(右上, ...