直接上代码记录一下
<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>
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mock.web.MockMultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Random;
public class QRCodeGenerator {
// 定义二维码的宽高
public static final int WIDTH = 300;
public static final int HEIGHT = 300;
// 定义头像的宽高
public static final int AVATAR_WIDTH = 50;
public static final int AVATAR_HEIGHT = 50;
// 默认头像
public static final String AVATAR_URL = "默认头像";
public static final String HTTP = "http://";
public static final String HTTPS = "https://";
public static final String TOP = "图片存储默认前缀";
public static final String PATH = "/opt/";
public static final String PNG = ".png";
public static final String FORMAT_NAME = "png";
public static final String CONTENT_TYPE = "text/plain";
public static QrcodeDto encodeReturn(String content, String avatarUrl) throws IOException, WriterException{
if(StringUtils.isBlank(avatarUrl)) {
avatarUrl = AVATAR_URL;
}
if (!avatarUrl.startsWith(HTTP) && !avatarUrl.startsWith(HTTPS)) {
avatarUrl = TOP + avatarUrl;
}
if(avatarUrl.startsWith(HTTP)) {
avatarUrl = avatarUrl.replace(HTTP, HTTPS);
}
String destPath = PATH;
// 创建QRCodeWriter对象
QRCodeWriter qrCodeWriter = new QRCodeWriter();
// 创建二维码对象
Map<EncodeHintType,Object> map = new HashMap<>();
map.put(EncodeHintType.CHARACTER_SET, "utf-8");
map.put(EncodeHintType.MARGIN, 1);
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 容错级别 H 最高 30%
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT,map);
// 下载头像图片
BufferedImage avatarImage = ImageIO.read(new URL(avatarUrl));
// 将头像图片添加到二维码图片中
BufferedImage bufferedImage = addAvatar(avatarImage, bitMatrix);
// 判断文件是否存在
if(!new File(destPath).exists()){
new File(destPath).mkdirs();
}
String fileName = new Random().nextInt(99999999) + PNG;//生成随机文件名
File file = new File(destPath + fileName);
ImageIO.write(bufferedImage, FORMAT_NAME, file);
FileInputStream fileInputStream = new FileInputStream(file);
String fileName1 = file.getName();
fileName = fileName1.substring((fileName1.lastIndexOf("/") + 1));
QrcodeDto qrcodeDto = new QrcodeDto();
qrcodeDto.setUrl(destPath + file);
qrcodeDto.setFile(new MockMultipartFile(fileName, fileName, CONTENT_TYPE, fileInputStream));
return qrcodeDto;
}
private static BufferedImage addAvatar(BufferedImage avatarImage, BitMatrix bitMatrix) {
BufferedImage bitMatrixImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 开始绘制二维码图片
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
// 二维码图片颜色(RGB)
bitMatrixImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
// 压缩头像图片
Image image = resizeImage(avatarImage);
// 计算头像图片的位置坐标
int x = (WIDTH - AVATAR_WIDTH) / 2;
int y = (HEIGHT - AVATAR_HEIGHT) / 2;
// 将头像图片添加到二维码图片中
Graphics2D graphics = bitMatrixImage.createGraphics();
graphics.drawImage(image, x, y, AVATAR_WIDTH, AVATAR_HEIGHT, null);
Shape shape = new RoundRectangle2D.Float(x, y, AVATAR_WIDTH, AVATAR_HEIGHT, 6, 6);
graphics.setStroke(new BasicStroke(3f));
graphics.draw(shape);
graphics.dispose();
return bitMatrixImage;
}
private static Image resizeImage(BufferedImage avatarImage) {
Image image = avatarImage.getScaledInstance(AVATAR_WIDTH, AVATAR_HEIGHT, Image.SCALE_SMOOTH);
BufferedImage bufferedImage = new BufferedImage(AVATAR_WIDTH, AVATAR_HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics graphics = bufferedImage.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
return image;
}
}
下面是更简单粗暴的方法
依赖
<dependency>
<groupId>com.github.liuyueyi.media</groupId>
<artifactId>qrcode-plugin</artifactId>
<version>2.5.5</version>
</dependency>
代码 只需几行就可生成带logo的图片 还可以生成特殊的形状
public static String qrUtilsCreate(String content, String avatarUrl) {
String fileName = new Random().nextInt(99999999) + PNG;//生成随机文件名
try {
BufferedImage image = QrCodeGenWrapper
.of(content)
.setH(500)
.setW(500)
.setLogo(avatarUrl)
.setLogoRate(8)
.setBgCornerRadiusRate(8) //设置背景圆角
.setBgImg("1.png") //背景图片
.setBgStyle(QrCodeOptions.BgImgStyle.PENETRATE) // 设置背景样式
.setDrawStyle(QrCodeOptions.DrawStyle.OCTAGON) // 设置画风格
.setLogoBorder(true)
.setLogoStyle(QrCodeOptions.LogoStyle.ROUND) // 设置圆角
.setDrawPreColor(Color.orange) // 设置前置色 不设置默认为黑色
.asBufferedImage();
File file = new File(PATH + fileName);
ImageIO.write(image, FORMAT_NAME, file);
} catch (Exception e) {
e.printStackTrace();
}
return PATH + fileName;
}