先上效果
文件结构
引入jar包
<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.zxing/javase --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.3.0</version>
</dependency>
QRCodeUtils 工具类
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.itextpdf.text.pdf.qrcode.ErrorCorrectionLevel;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.UUID;
public class QRCodeUtils {
// private static Integer WIDTH_PIX = 450;
// private static Integer HEIGHT_PIX = 500;
private static String TYPE = "JPEG";
private static String CHAR_TYPE = "UTF-8";
/**
* 二维码填充颜色
*/
//黑色
private static Integer COLOR_BLACK = 0XFF000000;
//白色
private static Integer COLOR_WHITE = 0XFFFFFFFF;
private static Integer COLOR_GREEN = 0xff00ff00;
private static Integer COLOR_PINK = 0xFFCBC0FF;
//二维码字体设置
private static String FONT_NAME = "Consolas";
//字体颜色
private static Color FONT_COLOR = Color.GREEN;
//字体大小
private static Integer FONT_SIZE =12;
/**
* 写入二维码
* @param text
* @param filePath
* @param logoPath
* @param COLOR
* @param width_pix
* @param height_pix
* @return
* @throws Exception
*/
public static File writeQRImg(String text,String filePath,String logoPath,Integer COLOR,Integer width_pix,Integer height_pix) throws Exception {
//配置参数
Hashtable<EncodeHintType,Object> hints= new Hashtable<EncodeHintType, Object>();
//字符编码
hints.put(EncodeHintType.CHARACTER_SET,CHAR_TYPE);
//容错级别
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN,3);
//生成二维码
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE,width_pix,height_pix,hints);
//得到二维码的宽高
int codeWidth = bitMatrix.getWidth();
int codeHeight = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(codeWidth,codeHeight,BufferedImage.TYPE_INT_RGB);
for (int i = 0;i<codeWidth;i++){
for (int j= 0;j<codeHeight;j++){
image.setRGB(i,j,bitMatrix.get(i,j)?COLOR:COLOR_WHITE);
}
}
//写入logo
writeLogo(image,logoPath,text);
File outPutImage= getQRImgFile(filePath);
//写入图片
ImageIO.write(image,TYPE,outPutImage);
return outPutImage;
}
/**
* 写logo
* @param image
* @param logoPath
* @param text
* @throws Exception
*/
private static void writeLogo(BufferedImage image, String logoPath,String text) throws Exception {
if (logoPath!=null&&logoPath.length()>0) {
File logoPic =new File(logoPath);
if (logoPic.exists()) {
BufferedImage logoBufferedImage=ImageIO.read(logoPic);
int widthLogo = logoBufferedImage.getWidth(null)>image.getWidth()*2/10?
(image.getWidth()*2/10):logoBufferedImage.getWidth(null);
int heightLogo= logoBufferedImage.getHeight(null)>image.getHeight()*2/10?
(image.getHeight()*2/10):logoBufferedImage.getHeight(null);
//设定在图片中间
int x=(image.getWidth()-widthLogo)/2;
int y=(image.getHeight()-heightLogo)/2;
//在原来基础上再加图片
Graphics2D graphics2D = image.createGraphics();
//绘制logo图片
graphics2D.drawImage(logoBufferedImage,x,y,widthLogo,heightLogo,null);
//绘制圆角矩形
graphics2D.drawRoundRect(x,y,widthLogo,heightLogo,15,15);
//设置边框宽度
graphics2D.setStroke(new BasicStroke(2));
//边框颜色
graphics2D.setColor(Color.WHITE);
graphics2D.drawRect(x,y,widthLogo,heightLogo);
//设置字体大小
Font font=new Font(FONT_NAME, Font.PLAIN,FONT_SIZE);
// graphics2D.setColor(FONT_COLOR);
// graphics2D.setFont(font);
// Integer fontStartIndex=image.getWidth()/2-(int)(text.length()*FONT_SIZE*0.7)/2;
// graphics2D.drawString(text,fontStartIndex,image.getHeight()-FONT_SIZE);
//释放图像资源
graphics2D.dispose();
logoBufferedImage.flush();
image.flush();
}
}
}
/**
* 得到二维码图片
* @param filePath
* @return
* @throws Exception
*/
private static File getQRImgFile(String filePath) throws Exception {
// String fileName= UUID.randomUUID().toString()+"."+TYPE;
String fileName= "newPic"+"."+TYPE;
File outPutImage = new File(filePath+File.separator+fileName);
if (outPutImage.exists()) {
outPutImage.delete();
}
outPutImage.createNewFile();
return outPutImage;
}
/**
* 写图片下方的水印
* @param pressText
* @param newImg
* @param targetImg
* @param fontStyle
* @param color
* @param fontSize
* @param width
* @param height
* @throws Exception
*/
public static void pressText(String pressText,String newImg,String targetImg,int fontStyle,
Color color,int fontSize,int width,int height) throws Exception {
//设置字体开始位置坐标
File file=new File(targetImg);
Image src=ImageIO.read(file);
int imageW=src.getWidth(null);
int imageH=src.getHeight(null);
BufferedImage image =new BufferedImage(imageW,imageH,BufferedImage.TYPE_INT_RGB);
Graphics graphics=image.createGraphics();
// int startX=(width/2-graphics.getFontMetrics().stringWidth(pressText)/2);
// int startY=height-(height-width)/2;
int startX=image.getWidth()/2-(int)(pressText.length()*FONT_SIZE*0.7)/2;
int startY=image.getHeight()-FONT_SIZE;
graphics.drawImage(src,0,0,imageW,imageH,null);
graphics.setColor(color);
graphics.setFont(new Font(null,fontStyle,fontSize));//设置字体
graphics.drawString(pressText,startX,startY);//写入文字
graphics.dispose();
FileOutputStream fileOutputStream= new FileOutputStream(newImg);
ImageIO.write(image,"JPEG",fileOutputStream);
//
JPEGImageEncoder jpegImageEncoder= JPEGCodec.createJPEGEncoder(fileOutputStream);
jpegImageEncoder.encode(image);
fileOutputStream.close();
System.out.println("image press success");
}
}
读取文件工具类 (写不写无所谓 方便定义文字而已)
import java.io.*;
public class ReadFromFile {
/**
* 读取文件
* @param src
* @return
*/
public static String readFromFile(File src){
try {
//汉字的字符集不匹配,比如说用UTF-8字符集去解析GBK字符集的汉字就会变成乱码
// 这里不要用FileReader,这个类用的是默认字符集去读取文本,改用InputStreamReader,它的构造方法中能够指定字符集,让它作为BufferedReader的源,就不会乱码了
// 如果还是乱码,就把GBK改成UTF-8
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(src),"GBK"));
FileInputStream fileInputStream = new FileInputStream(src);
BufferedInputStream bufferedInputStream= new BufferedInputStream(fileInputStream);
StringBuilder stringBuilder = new StringBuilder();
String content=null;
while ((content=bufferedReader.readLine())!=null){
stringBuilder.append(content);
stringBuilder.append("\r\n");
}
return stringBuilder.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
测试类
import org.junit.Test;
import java.awt.*;
import java.io.File;
public class QRCodeUtilsTest {
private static Integer COLOR_BLACK = 0XFF000000;
//白色
private static Integer COLOR_WHITE = 0XFFFFFFFF;
private static Integer COLOR_GREEN = 0xff00ff00;
private static Integer COLOR_PINK = 0xE86CA0;
@Test
public void testWriteQRImg() throws Exception {
String outPath="D:/QRCodetest";
String newImg="D:/QRCodetest/imageWithText.jpg";
String targetImg="D:/QRCodetest/newPic.jpeg";
int fontStyle=1;
int fontSize=20;//字体大小
int width=800;
int height=800;
File pressFile =new File("D:/QRCodetest/pressText.txt");
String pressText =ReadFromFile.readFromFile(pressFile);
//读取文件 转为字符串
File file=new File("D:/QRCodetest/text.txt");
String text=ReadFromFile.readFromFile(file);
QRCodeUtils.writeQRImg(text,outPath,"D:/QRCodetest/logo.jpg",COLOR_PINK,width,height);
QRCodeUtils.pressText(pressText,newImg,targetImg,fontStyle, Color.BLACK,fontSize,width,height);
}
}
完毕
参考博客: