直接上代码:效果如下图
需引入 zxing生成二维码包
<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>
方法实现如下:
controller
//生成二维码并将其存放于本地目录
@PostMapping("/generate/v1")
public Response generateV1(String content){
Response response=new Response();
try {
final String fileName=LOCALDATEFORMAT.get().format(new Date());
QRCodeUtil.createCodeToFile(content,new File(RootPath),fileName+FileFormat);
}catch (Exception e){
response=new Response(false,e.getMessage());
}
return response;
}
utils工具类
createCodeToFile
public static void createCodeToFile(String content, File codeImgFileSaveDir, String fileName) {
try {
if (StringUtils.isBlank(content) || StringUtils.isBlank(fileName)) {
return;
}
content = content.trim();
if (codeImgFileSaveDir==null || codeImgFileSaveDir.isFile()) {
//二维码图片存在目录为空,默认放在桌面...
codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory();
}
if (!codeImgFileSaveDir.exists()) {
//二维码图片存在目录不存在,开始创建...
codeImgFileSaveDir.mkdirs();
}
//核心代码-生成二维码
BufferedImage bufferedImage = getBufferedImage(content,1);
File codeImgFile = new File(codeImgFileSaveDir, fileName);
ImageIO.write(bufferedImage, "png", codeImgFile);
log.info("二维码图片生成成功:" + codeImgFile.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
核心代码:生成二维码
getBufferedImage
private static BufferedImage getBufferedImage(String content,Integer number) throws WriterException {
//com.google.zxing.EncodeHintType:编码提示类型,枚举类型
Map<EncodeHintType, Object> hints = new HashMap();
//EncodeHintType.CHARACTER_SET:设置字符编码类型
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//EncodeHintType.ERROR_CORRECTION:设置误差校正
//ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
//不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
//EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
hints.put(EncodeHintType.MARGIN, 1);
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
for (int x = 0; x < CODE_WIDTH; x++) {
for (int y = 0; y < CODE_HEIGHT; y++) {
bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
}
}
// 生成二维码图像
// 创建新的BufferedImage,用于合并二维码和数字
int QR_IMAGE_BOTTOM_PADDING = 30;
int NUMBER_FONT_SIZE = 30;
int numberWidth = bufferedImage.getWidth() / 3; // 假设数字宽度大约为二维码宽度的1/3
int combinedImageHeight = CODE_HEIGHT + QR_IMAGE_BOTTOM_PADDING + NUMBER_FONT_SIZE;
BufferedImage combinedImage = new BufferedImage(CODE_WIDTH, combinedImageHeight, BufferedImage.TYPE_INT_BGR);
// 复制二维码图像到新图像的顶部
Graphics2D g2d = combinedImage.createGraphics();
g2d.drawImage(bufferedImage, 0, 0, null);
// 设置字体和颜色
g2d.setFont(new Font("Monospaced", Font.BOLD, NUMBER_FONT_SIZE));
g2d.setColor(Color.WHITE);
// 计算数字的坐标以保持居中
int numberX = (CODE_WIDTH - numberWidth) / 2;
int numberY = CODE_HEIGHT + QR_IMAGE_BOTTOM_PADDING;
// 在新图像的底部绘制数字
g2d.drawString(Integer.toString(number), numberX, numberY);
g2d.dispose();
return combinedImage;
}