依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
代码1
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.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
public class QRCodeUtil {
public static final String FORMAT = "jpg";
private static final String FONT_STR = "华文细黑";
private final Logger log = LoggerFactory.getLogger(this.getClass());
public void generate(Integer width, Integer height, Integer margin, String text, String path){
HashMap hashMap = new HashMap();
hashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hashMap.put(EncodeHintType.MARGIN, margin);
File qrFile = new File(path);
File qrParent = new File(qrFile.getParent());
if(!qrParent.exists())
qrParent.mkdirs();
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hashMap);
MatrixToImageWriter.writeToPath(bitMatrix, FORMAT,qrFile.toPath());
} catch (WriterException e) {
log.error("[二维码]生成二维码失败", e);
e.printStackTrace();
} catch (IOException e) {
log.error("[二维码]生成二维码异常[path: " + path + "]", e);
e.printStackTrace();
}
}
public void generate(Integer width, Integer height, Integer margin, String text, String path, String logoPath){
this.generate(width, height, margin, text, path);
try {
this.generateWithLogo(path, logoPath);
} catch (IOException e) {
log.error("[二维码]生成带logo的二维码异常[QRCode: " + path + ", logo: " + logoPath + "]", e);
e.printStackTrace();
}
}
public void generate(Integer size, String text, String path, String logoPath, String info){
Integer width = size;
Integer fontSize = size / 25;
Integer height = width;
this.generate(width, height, 3, text, path);
try {
this.generateWithLogo(path, logoPath);
this.drawTextInImg(path, info, path, fontSize, FONT_STR);
} catch (IOException e) {
log.error("[二维码]生成带logo的二维码异常[QRCode: " + path + ", logo: " + logoPath + "]", e);
e.printStackTrace();
}
}
public void generate(Integer size, String text, String path, String info){
Integer width = size;
Integer fontSize = size / 25;
Integer height = width + fontSize * 2;
this.generate(width, height, 3, text, path);
try {
this.drawTextInImg(path, info, path, fontSize, FONT_STR);
} catch (IOException e) {
log.error("[二维码]添加文字描述异常[QRCodePath: " + path + "]", e);
e.printStackTrace();
}
}
private void generateWithLogo(String path, String logoPath) throws IOException{
File file = new File(path);
BufferedImage matrixImage = ImageIO.read(file);
Graphics2D g2 = matrixImage.createGraphics();
int matrixWidth = matrixImage.getWidth();
int matrixHeigh = matrixImage.getHeight();
BufferedImage logo = ImageIO.read(new File(logoPath));
g2.drawImage(logo.getScaledInstance(matrixWidth/5, matrixWidth/5, Image.SCALE_SMOOTH),matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);
BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);
RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.white);
g2.draw(round);
BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
g2.setColor(new Color(128,128,128));
g2.draw(round2);
g2.dispose();
logo.flush();
matrixImage.flush() ;
ImageIO.write(matrixImage, FORMAT, file);
}
private void generateWithCubeLogo(String path, String logoPath) throws IOException {
BufferedImage i = ImageIO.read(new File(path));
Integer qrWidth = i.getWidth();
Integer qrHeight = i.getHeight();
BufferedImage image = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < qrWidth; x++) {
for (int y = 0; y < qrHeight; y++) {
image.setRGB(x, y, i.getRGB(x, y));
}
}
int width = image.getWidth();
int height = image.getHeight();
Graphics2D g = image.createGraphics();
BufferedImage logo = ImageIO.read(new File(logoPath));
g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
g.dispose();
logo.flush();
ImageIO.write(image, "jpg", new File(path));
}
private void drawTextInImg(String filePath, String text, String outPath,int fontSize, String fontStr) throws IOException {
BufferedImage img = ImageIO.read(new File(filePath));
int width = img.getWidth();
int height = img.getHeight();
BufferedImage bimage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Integer n = text.replaceAll("[\\u4e00-\\u9fa5]", "aa").length();
Graphics2D g = bimage.createGraphics();
int rectX = (img.getWidth() - fontSize * n / 2) / 2;
int rectY = img.getHeight() - fontSize;
Font font = new Font(fontStr, Font.PLAIN, fontSize);
g.setBackground(Color.white);
g.drawImage(img, 0, 0, null);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setPaint(Color.black);
g.setFont(font);
g.drawString(text, rectX, rectY);
g.dispose();
try {
ImageIO.write(bimage, "jpg", new File(outPath));
} catch (FileNotFoundException e) {
log.error("[二维码]添加文字描述时找不到指定路径【path: " + outPath + "】", e);
e.printStackTrace();
} catch (IOException e) {
log.error("[二维码]添加文字描述时IO异常【path: " + outPath + "】", e);
e.printStackTrace();
}
bimage.flush();
}
}
代码2
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.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
public class QRCodeUtil {
private static final String FONT_STR = "华文细黑";
private final Logger log = LoggerFactory.getLogger(this.getClass());
public BufferedImage generate(Integer width, Integer height, Integer margin, String text){
return this.generateQRCode(width, height, margin, text);
}
public BufferedImage generate(Integer width, Integer height, Integer margin, String text, String logoPath){
BufferedImage qrCode = this.generateQRCode(width, height, margin, text);
try {
this.addLogoImage(qrCode, logoPath);
return qrCode;
} catch (IOException e) {
log.error(" [二维码]logo图片异常,path: " + logoPath, e);
}
throw new RuntimeException("二维码生成失败");
}
public BufferedImage generate(Integer size, String text, String logoPath, String info){
BufferedImage qrCode = this.generateQRCode(size, size, 3, text);
try {
this.addLogoImage(qrCode, logoPath);
this.addText(qrCode, info, size / 25, FONT_STR);
return qrCode;
} catch (IOException e) {
log.error(" [二维码]logo图片异常,path: " + logoPath, e);
}
throw new RuntimeException("二维码生成失败");
}
public BufferedImage generate(Integer size, String text, String info){
BufferedImage qrCode = this.generateQRCode(size, size, 3, text);
this.addText(qrCode, info, size / 25, FONT_STR);
return qrCode;
}
private BufferedImage generateQRCode(Integer width, Integer height, Integer margin, String text){
HashMap hashMap = new HashMap();
hashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hashMap.put(EncodeHintType.MARGIN, margin);
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hashMap);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bufferedImage.getGraphics().drawImage(MatrixToImageWriter.toBufferedImage(bitMatrix), 0, 0, null);
return bufferedImage;
} catch (WriterException e) {
log.error("[二维码]生成二维码失败", e);
}
log.error("[二维码]生成二维码失败");
throw new RuntimeException("二维码生成失败");
}
private void addLogoImage(BufferedImage matrixImage, String logoPath) throws IOException {
Graphics2D g2 = matrixImage.createGraphics();
int matrixWidth = matrixImage.getWidth();
int matrixHeigh = matrixImage.getHeight();
BufferedImage logo = ImageIO.read(new File(logoPath));
g2.drawImage(logo.getScaledInstance(matrixWidth/5, matrixWidth/5, Image.SCALE_SMOOTH),matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);
BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);
RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.white);
g2.draw(round);
BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
g2.setColor(new Color(128,128,128));
g2.draw(round2);
g2.dispose();
logo.flush();
matrixImage.flush();
}
private void addText(BufferedImage matrixImage, String text, int fontSize, String fontStr){
Integer n = text.replaceAll("[\\u4e00-\\u9fa5]", "aa").length();
Graphics2D g = matrixImage.createGraphics();
int rectX = (matrixImage.getWidth() - fontSize * n / 2) / 2;
int rectY = matrixImage.getHeight() - fontSize;
Font font = new Font(fontStr, Font.PLAIN, fontSize);
g.setBackground(Color.red);
g.drawImage(matrixImage, 0, 0, null);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setPaint(Color.black);
g.setFont(font);
g.drawString(text, rectX, rectY);
g.dispose();
matrixImage.flush();
}
}
效果图