一、效果图
二、代码示例:
1. 引入依赖
com.google.zxing
core
3.3.0
com.google.zxing
javase
3.3.3
2. 底层+图标图片
3. 创建二维码
①工具类:QRCodeUtil
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* @author matx
* @description: 生成二维码
* @date 2022/8/1814:02
*/
public class QRCodeUtil {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
//二维码颜色
private static final int BLACK = 0xFF000000;
//二维码颜色
private static final int WHITE = 0xFFFFFFFF;
/**
* @param text 请求地址
* @param width 图片长度
* @param height 图片高度
* @param logoPath logo路径
* @param code 溯源码唯一code
* @param smallLogo 最中间的logo
* @param formatName 最终文件形式
*/
public static String createImg(String text, int width, int height,
String logoPath,String code,String formatName,String smallLogo) {
Map his = new HashMap();
//设置编码字符集
his.put(EncodeHintType.CHARACTER_SET, "utf-8");
String resultPath = "";
try {
//1、生成二维码
BitMatrix encode = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, his);
//2、获取二维码宽高
int codeWidth = encode.getWidth();
int codeHeight = encode.getHeight();
//3、将二维码放入缓冲流
BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < codeWidth; i++) {
for (int j = 0; j < codeHeight; j++) {
//4、循环将二维码内容定入图片
image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);
}
}
//设置圆角
image = setClip(image, 400);
// String fileName = filePath + code+".jpg";
String fileName = code + ".jpg";
//5、将二维码写入图片
File outPutImage = new File(fileName);
// 构建绘图对象
Graphics2D g = image.createGraphics();
// 读取网络Logo图片
URL smallUrl = new URL(smallLogo);
// 读取本地Logo图片
//BufferedImage logo = ImageIO.read(new File(smallLogo));
// 读取网络Logo图片
BufferedImage logo = ImageIO.read(smallUrl);
// 开始绘制logo图片
g.drawImage(logo, image.getWidth() * 2 / 5, image.getHeight() * 2 / 5, image.getWidth() * 2 / 10, image.getHeight() * 2 / 10, null);
g.dispose();
logo.flush();
image.flush();
ImageIO.write(image, "jpg", outPutImage);
System.out.println("二维码生成成功");
//resultPath = filePath + code + ".jpg";
resultPath = code + ".jpg";
//二维码嵌入底层logo
resultPath = mergeImage(logoPath, fileName, resultPath, formatName);
} catch (Exception e) {
e.printStackTrace();
System.out.println("二维码图片生成失败");
}
return resultPath;
}
/**
* 图片切圆角
* @param srcImage
* @param radius
* @return
*/
public static BufferedImage setClip(BufferedImage srcImage, int radius) {
int width = srcImage.getWidth();
int height = srcImage.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D gs = image.createGraphics();
gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gs.setClip(new RoundRectangle2D.Double(0, 0, width, height, radius, radius));
gs.drawImage(srcImage, 0, 0, null);
gs.dispose();
return image;
}
/**
* 将二维码写入到logo文件中
* @param logoPath logo文件地址
* @param qrPath 生成的二维码存放地址
* @param resultPath 最终的文件地址
* @param formatName 最终文件形式
* @throws IOException
*/
public static String mergeImage(String logoPath,String qrPath,String resultPath,String formatName)throws IOException {
// 读取本地文件
// File srcImgFile = new File(logoPath);
// Image srcImg = ImageIO.read(srcImgFile);
// 读取原图片信息(logo)
URL logoUrl = new URL(logoPath);
//将文件对象转化为图片对象
Image srcImg = ImageIO.read(logoUrl);
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
//开始加水印 创建画笔
Graphics2D g = bufImg.createGraphics();
//绘制原始图片
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
// 水印文件
Image srcWaterMark = ImageIO.read(new File(qrPath));
//获取水印图片的宽度
int widthWaterMark= srcWaterMark.getWidth(null);
//获取水印图片的高度
int heightWaterMark = srcWaterMark.getHeight(null);
//设置 alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));
//绘制水印图片 坐标为中间位置
g.drawImage(srcWaterMark, (srcImgWidth - widthWaterMark) / 2,
(srcImgHeight - heightWaterMark) / 2, widthWaterMark, heightWaterMark, null);
// 水印文件结束
g.dispose();
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(resultPath);
ImageIO.write(bufImg, formatName, outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
return resultPath;
}
public static void main(String[] args) throws IOException {
String paths = "D:\\img\\yuan.png";
System.out.println(paths);
String text = "https://taceability.lpsrn.com.cn/prod-api/traceability/qrcode/getCodeValueByCode/?code=001001202208140120220815PD2022081600000000";
createImg(text, 248, 248,
paths, "001001202208140120220815PD2022081600000000", "png","D:\\img\\small.png");
}
}
②接口调用
@GetMapping(value = "/createCode/{code}")
public AjaxResult createQRCode(@PathVariable("code")String code){
//请求地址
String text = "https://rance.lpsrn.com.cn/prod-api/traceability/qrcode/getCodeValueByCode/?code="+code;
AjaxResult ajaxResult = new AjaxResult();
logger.info("【生成二维码接口】,请求参数:{}",code);
try {
String diLogoPath = "https://n.oss-cn-beijing.aliyuncs.com/qrcode/20220824/8492a1e45f2745c384e0581317784790/logo.png";
String smallPath = "https://n.oss-cn-beijing.aliyuncs.com/qrcode/20220824/16358df1a42c4191abdb6f2302e5a700/small.png";
//图标在本地时使用
// String diLogoPath = "D:\\img\\logo.png";
// String smallPath = "D:\\img\\small.png";
String formatName = "png";
String resultPath = QRCodeUtil.createImg(text,
1048, 1048, diLogoPath, code,formatName,smallPath);
File file = new File(resultPath);
if (file == null) {
return AjaxResult.error("文件内容为空");
}
ajaxResult.put("url", ossPath);
ajaxResult.put("code",200);
}catch(Exception e){
logger.error("【生成二维码接口】异常信息:{}",e.getMessage());
return AjaxResult.error("系统异常");
}
logger.error("【生成二维码接口】响应信息:{}",JSON.toJSONString(ajaxResult));
return ajaxResult;
}