具体实现步骤如下:
1.导入pom依赖:
com.google.zxing
core
3.4.0
com.google.zxing
javase
3.4.0
2.编写一个工具类
package com.example.util;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class ZxingUtils {
/**
* // 二维码生成
* @param contents 说明
* @param width 宽
* @param height 高
* @param margin 边框
* @return BufferedImage
* @throws Exception
*/
public static BufferedImage createQRImage(String contents, int width, int height, int margin) throws Exception {
BufferedImage qRImage = null;
if (contents == null || "".equals(contents)) {
throw new Exception("content说明不能为空");
}
// 二维码参数设置
HashMap hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, CharacterSetECI.UTF8); // 编码设置
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 安全等级,最高h
hints.put(EncodeHintType.MARGIN, margin); // 设置margin=0-10
// 二维码图片的生成
BarcodeFormat format = BarcodeFormat.QR_CODE;
// 创建矩阵容器
BitMatrix matrix = null;
try {
matrix = new MultiFormatWriter().encode(contents, format, width, height, hints);
} catch (WriterException e) {
e.printStackTrace();
}
// 设置矩阵转为图片的参数
MatrixToImageConfig toImageConfig = new MatrixToImageConfig(Color.black.getRGB(), Color.white.getRGB());
// 矩阵转换图像
qRImage = MatrixToImageWriter.toBufferedImage(matrix, toImageConfig);
return qRImage;
}
public static BufferedImage addQRImagelogo(BufferedImage qrImage, int width, int height, String logoPath, int logoSize) throws Exception {
// 二维码添加logo
BufferedImage qRImageWithLogo = null;
File logoFile = new File(logoPath);
if (!logoFile.exists() || !logoFile.isFile()) {
throw new Exception("指定的logo图片不存在");
}
// 处理logo
BufferedImage image = ImageIO.read(logoFile);
// 设置logo的高和宽
int logoHeight = qrImage.getHeight()/logoSize;
int logoWidth = qrImage.getWidth()/logoSize;
// 设置放置位置
int x = (qrImage.getHeight() - logoHeight) / 2;
int y = (qrImage.getWidth() - logoWidth) / 2;
// 新建画板
qRImageWithLogo = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 新建画笔
Graphics2D g = (Graphics2D) qRImageWithLogo.getGraphics();
// 将二维码绘制到画板
g.drawImage(qrImage, 0, 0, null);
// 设置头透明度,可设置范围0.0f-1.0f
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
// 绘制logo
g.drawImage(image, x, y, logoWidth, logoHeight, null);
return qRImageWithLogo;
}}
3.编写service类
package com.example.service;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
@Service
public class QRCodeService {
public String crateQRCode(String content,int width,int height) throws IOException{
String resultImage = “”;
if(!StringUtils.isEmpty(content)){
ServletOutputStream stream = null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
@SuppressWarnings(“rawtypes”)
HashMap
hints.put(EncodeHintType.CHARACTER_SET,“utf-8”);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//指定二维码的纠错等级为中级
hints.put(EncodeHintType.MARGIN,2); //设置图片边距
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, "png", os);
/**
* 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析,可以让前端加,也可以在下面加上
*/
resultImage = new String("data:image/png;base64," + Base64.encode(os.toByteArray()));
return resultImage;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
stream.flush();
stream.close();
}
}
}
return null;
}
}
4.编写controller
package com.example.conroller;
import com.example.util.ZxingUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@Controller
public class DemoControler {
// 和验证码的实现原理是一样,是不过换了一种验证方式。
@RequestMapping("/createQRcode")
public void createQRcode(HttpServletResponse response)throws IOException {
String contents = "https://www.baidu.com/";
int width = 100;
int height = 100;
int margin = 2;
try {
BufferedImage QRcode = ZxingUtils.createQRImage(contents, width, height, margin);
String logoPath = "C:\\Users\\Administrator\\Desktop\\spring boot资料\\aaa.png";
int logoSize = 4;
BufferedImage qRImageWithLogo = ZxingUtils.addQRImagelogo(QRcode, width, height, logoPath, logoSize);
// 写入返回
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(qRImageWithLogo, "jpg", baos);
byte[] QRJPG = baos.toByteArray();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
//写入本地磁盘
OutputStream os2 = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\newbee-mall\\text.png");
os2.write(QRJPG, 0, QRJPG.length);
os2.flush();
os2.close();
ServletOutputStream os = response.getOutputStream();
os.write(QRJPG); // 自此完成一套,图片读入,写入流,转为字节数组,写入输出流
os.flush();
os.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
response.sendRedirect(contents); //扫码后跳转百度
}
}