导入以下包:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
代码如下:
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class QrCodeUtil {
//0x,透明度,R,G,B
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final String FORMAT_NAME = "png";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
// LOGO宽度
private static final int WIDTH = 60;
// LOGO高度
private static final int HEIGHT = 60;
/**
* 生成二维码代码
*
* @param contents 二维码内容
* @return 二维码的描述对象 BitMatrix
* @throws WriterException 编码时出错
*/
public static BitMatrix encode(String contents) throws WriterException {
final Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
return new QRCodeWriter().encode(contents, BarcodeFormat.QR_CODE, 320, 320, hints);
}
/**
* 二维码图片生成
* @param matrix
* @return
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
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;
}
/**
* 二维码输出为文件
* @param image 二维码图片
* @param format 二维码图片格式
* @param filePath 二维码保存路径
* @throws IOException
*/
public static void writeToFile(BufferedImage image, String format, String filePath) throws IOException {
File outputFile = new File(filePath);
if (!outputFile.exists()) {
outputFile.mkdirs();
}
if (!ImageIO.write(image, format, outputFile)) {
throw new IOException("不能转换成" + format );
}
}
/**
* 二维码添加logo(logo占二维码1/5)
* @param image 二维码图片
* @param logoFilePath logo图片路径
* @return
* @throws IOException
*/
public static BufferedImage addLogo(BufferedImage image, String logoFilePath) throws IOException {
File file = new File(logoFilePath);
if (!file.exists()) {
throw new IOException("logo文件不存在");
}
BufferedImage logo = ImageIO.read(file);
Graphics2D graph = image.createGraphics();
graph.drawImage(logo, image.getWidth() * 2 / 5, image.getHeight() * 2 / 5
, image.getWidth() * 2 / 10, image.getHeight() * 2 / 10, null);
graph.dispose();
return image;
}
/**
* 二维码添加背景
* @param image 二维码图片
* @param bgFilePath 背景图片路径
* @param x 维码左顶点在背景图片的X坐标
* @param y 二维码左顶点在背景图片的Y坐标
* @return
* @throws IOException
*/
public static BufferedImage addBgImg(BufferedImage image, String bgFilePath, int x, int y) throws Exception {
File file = new File(bgFilePath);
if (!file.exists()) {
throw new IOException("背景图片不存在");
}
BufferedImage bgImg = ImageIO.read(file);
if(x < 0) {
x = 0;
}
if(y < 0) {
y = 0;
}
if(bgImg.getWidth() < image.getWidth() || bgImg.getHeight() <image.getHeight()) {
throw new Exception("背景图片小于二维码尺寸");
}
if(bgImg.getWidth() < x + image.getWidth() || bgImg.getHeight() < y + bgImg.getHeight()) {
throw new Exception("以背景的("+x+","+y+")作为二维码左上角不能容下整个二维码");
}
Graphics2D graph = bgImg.createGraphics();
graph.drawImage(image, x, y, image.getWidth(), image.getHeight(), null);
graph.dispose();
return bgImg;
}
/**
* 二维码底部添加文本(只限一行,没有换行)
* @param image 二维码图片
* @param text 文本内容
* @param fontSize 写入文本的字体
* @return
*/
public static BufferedImage addText(BufferedImage image, String text, int fontSize) {
int outImageWidth = image.getWidth();
int outImageHeight = image.getHeight() + fontSize + 10;
BufferedImage outImage = new BufferedImage(outImageWidth, outImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graph = outImage.createGraphics();
//填充为白色背景
graph.setColor(Color.white);
graph.fillRect(0 ,0 , outImageWidth, outImageHeight);
//将二维码画入
graph.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
//添加文本
graph.setColor(Color.black);
Font font = new Font("楷体", Font.BOLD, fontSize);//字体,字型,字号
graph.setFont(font);
//文本水平,垂直居中
FontRenderContext frc =
new FontRenderContext(null, true, true);
Rectangle2D r2D = font.getStringBounds(text, frc);
int rWidth = (int) Math.round(r2D.getWidth());
int a = (outImageWidth - rWidth) / 2;
graph.drawString(text,a, outImageHeight - 5);//x,y为左下角坐标
graph.dispose();
return outImage;
}
/**
* 生成二维码(无logo,无背景)
* 根据内容,生成指定宽高、指定格式的二维码图片
* @param text 内容
* @param width 宽
* @param height 高
* @return
* @throws Exception
*/
public static BufferedImage encodeQrCode(String text, int width, int height) throws WriterException, IOException {
//设置二维码配置
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 设置QR二维码的纠错级别,指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 0);// 白边
//创建比特矩阵(位矩阵)的QR码编码的字符串
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
//二维码图片生成
BufferedImage qrCodeImg = toBufferedImage(bitMatrix);
return qrCodeImg;
}
/**
* 解析二维码
* @param image 读入的二维码图片
* @return
*/
public static String decodeQrCode(BufferedImage image) {
String qrCodeContent = null;
try {
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码
qrCodeContent= result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return qrCodeContent;
}
}
测试:
public class QrCodeUtilTest {
public static BufferedImage bi = null;
public static BitMatrix bitMatrix = null;
public static BufferedImage bufferedImage = null;
@Test
public void encode() {
try {
//生成二维码代码
bitMatrix = QrCodeUtil.encode("are you ok");
} catch (WriterException e) {
e.printStackTrace();
}
}
@Test
public void toBufferedImage() {
//生成二维码图片
bufferedImage = QrCodeUtil.toBufferedImage(bitMatrix);
}
@Test
public void writeToFile() {
try {
//生成一个随机的文件名
String fileName = UUID.randomUUID().toString().replaceAll("-", "");
//将图片存起来
QrCodeUtil.writeToFile(bufferedImage, "png", "D:\\2\\" + fileName + ".png");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void addLogo() {
try {
//添加二维码logo,并生成二维码
BufferedImage bufferedImage1=QrCodeUtil.addLogo(bufferedImage,"D:\\2\\电影票.svg");
//生成一个随机的文件名
String fileName = UUID.randomUUID().toString().replaceAll("-", "");
//将图片存起来
QrCodeUtil.writeToFile(bufferedImage1, "png", "D:\\2\\" + fileName + ".png");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void addBgImg() {
try {
//生成二维码背景图片
BufferedImage bufferedImage2=QrCodeUtil.addBgImg(bufferedImage,"D:\\2\\电影票.png",0,0);
//生成一个随机的文件名
String fileName = UUID.randomUUID().toString().replaceAll("-", "");
//将图片存起来
QrCodeUtil.writeToFile(bufferedImage2, "png", "D:\\2\\" + fileName + ".png");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void addText() {
}
@Test
public void encodeQrCode() {
try {
//生成二维码图片,二维码内容,二维码大小
BufferedImage bi = QrCodeUtil.encodeQrCode("你好啊", 100, 100);
//将生成的流写入到文件中
QrCodeUtil.writeToFile(bi, "png", "D:\\2\\3.png");
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void decodeQrCode() {
try {
//从路径中读取二维码,将图片加载到内存中
String imgPath = "D:\\2\\3.png";
BufferedImage image = ImageIO.read(new FileInputStream(imgPath));
//解析二维码,并输出相应的内容
System.out.println(QrCodeUtil.decodeQrCode(image));
} catch (IOException e) {
e.printStackTrace();
}
}
}