并没有太多的变动,其实这段代码还有一个bug,就是logo上去是黑色的,丑的不得了。马赛克是我自己加的,实在是不好意思分享网址。

public class PhotoQrCode extends Render {
private static final MatrixToImageConfig DEFAULT_CONFIG = new MatrixToImageConfig();
private String content;
private int width;
private int height;
private ErrorCorrectionLevel errorCorrectionLevel;
/**
* 构造方法,经测试不指定纠错参数时,默认使用的是 'L' 最低级别纠错参数
*
* @param content
* 二维码携带内容
* @param width
* 二维码宽度
* @param height
* 二维码高度
*/
public PhotoQrCode(String content, int width, int height) {
init(content, width, height, null);
}
private void init(String content, int width, int height, ErrorCorrectionLevel errorCorrectionLevel) {
if (StrKit.isBlank(content)) {
throw new IllegalArgumentException("content 不能为空");
}
if (width < 0 || height < 0) {
throw new IllegalArgumentException("width 与 height 不能小于 0");
}
this.content = content;
this.width = width;
this.height = height;
this.errorCorrectionLevel = errorCorrectionLevel;
}
@Override
public void render() {
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/png");
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 0); // 去掉白色边框,极度重要,否则二维码周围的白边会很宽
if (errorCorrectionLevel != null) {
hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
}
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
// 经测试 200 X 200 大小的二维码使用 "png" 格式只有 412B,而 "jpg" 却达到 15KB
String path = request.getSession().getServletContext().getRealPath("/static/QrCodeImg/logo.png");
overlapImage(bitMatrix, "png", response.getOutputStream(), path);
} catch (Exception e) {
throw new RenderException(e);
}
}
/**
* 将照片logo添加到二维码中间
* @param matrix
* @param format
* @param stream
* @param logoPath
* @throws IOException
*/
public void overlapImage(BitMatrix matrix, String format, OutputStream stream, String logoPath) throws IOException {
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix, DEFAULT_CONFIG);
BufferedImage logo = ImageIO.read(new File(logoPath));
Graphics2D g = image.createGraphics();
// 考虑到logo照片贴到二维码中,建议大小不要超过二维码的1/5;
int width = image.getWidth() / 3;
int height = image.getHeight() / 3;
// logo起始位置,此目的是为logo居中显示
int x = (image.getWidth() - width) / 2;
int y = (image.getHeight() - height) / 2;
// 绘制图
g.drawImage(logo, x, y, width, height, null);
g.dispose();// 清理内存中的图片,返还内存给系统
// 输出二维码
ImageIO.write(image, format, stream);
}
}