一、生成二维码
1、导入依赖
<dependency>
<groupId>QRCode</groupId>
<artifactId>QRCode</artifactId>
<version>3.0</version>
</dependency>
2、编写生成二维码方法
传入参数为二维码信息
public static BufferedImage qrcodeBase64(String msg) throws Exception {
Qrcode x = new Qrcode();
//N代表数字,A代表a-z,B代表其他字符
x.setQrcodeEncodeMode('B');
//设置纠错等级
x.setQrcodeErrorCorrect('M');
//设置版本号(1-40)
x.setQrcodeVersion(7);
int width = 67 + 12*(7-1);
int height = 67 + 12*(7-1);
int pixoff=2;//偏移量
BufferedImage bufferedImage = new BufferedImage(width,height,
BufferedImage.TYPE_INT_BGR);
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.setColor(Color.BLACK);
gs.clearRect(0, 0, width, height);
byte[] d = msg.getBytes("UTF-8");
if(d.length>0&&d.length<120) {
boolean[][] s = x.calQrcode(d);
for(int i=0;i<s.length;i++) {
for(int j=0;j<s.length;j++) {
if(s[j][i]) {
gs.fillRect(j*3+pixoff, i*3+pixoff, 3, 3);
}
}
}
}
gs.dispose();
bufferedImage.flush();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "bmp", bos);
return bufferedImage;
}
二、绘图
1、编写一个画图类
并设置好所有需要的参数
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Random;
public class CreatImg {
// 图片长宽(分辨率)
public static int width = 1080;
public static int height = 1920;
// 头像大小
public static int headerWidth = 240;
public static int headerHeight = 240;
// 背景图片大小
public static int backImgWidth = 1080;
public static int backImgHeight = 800;
// 二维码大小
public static int qrcodeWidth = 720;
public static int qrcodeHeight = 720;
// 用户头像图片
private static String headerUrl = "img/userAvatar@3x.png";
// 用户所在机构名
private static String title = "喜猫猫与灰太猫大型工厂";
// 用户名
private static String name = "喜先生";
// 用户手机号
private static String phone = "12345678911";
// 用户职工号
private static String str = "123456";
// 用户手机号json字符串格式,用于生成二维码
private static String phoneBytes = "{manager_bind: \"0DC2F7DC7D24E1E1A163592D6BCA124E6363E319A7A09E99\"}";
}
2、绘制主要类
其中参数分别为用户头像,用户机构,用户名,用户手机号,用户职工号,手机号json字符串
可根据实际情况自行设置参数,并对其操作绘制
public static File getImage(String headerUrl, String title, String name, String phone, String str, String phoneBytes) throws Exception {
// 创建一个画板
BufferedImage sourceImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
// 读取用户头像(所有现有的图片都存在我的本地项目中)
BufferedImage goodImage = ImageIO.read(Resource.class.getClassLoader().getResourceAsStream(headerUrl)); // "img/userAvatar@3x.png"
// 读取用户手机号的json字符串
BufferedImage qrcodeImg = QrCodeUtil.qrcodeBase64(phoneBytes);
// 读取背景图片
BufferedImage bussinesscard = ImageIO.read(Resource.class.getClassLoader().getResourceAsStream("img/bussinesscardBg5.png"));
// Graphics可以对图像进行绘画等操作
Graphics2D graphics = sourceImg.createGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
// 绘制二维码(x,y轴以及大小)
graphics.drawImage(qrcodeImg, 180, 880, qrcodeWidth, qrcodeHeight, null);
// 绘制背景图
graphics.drawImage(bussinesscard, 0, 0, backImgWidth, backImgHeight, null);
// 绘制头像
graphics.drawImage(goodImage, 720, 300, headerWidth, headerHeight, null);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
// 绘制机构名
Font f = new Font("黑体", Font.PLAIN, 60);
graphics.setPaint(new Color(255, 255, 255));
graphics.setFont(f);
// 长度大于13时换行
if (title.length() > 13) {
String line1 = title.substring(0,14);
graphics.drawString(line1, 80, 150);
String line2 = title.substring(14);
// 换行后长度大于12时用...代替剩余部分
if (line2.length() > 12) {
line2 = line2.substring(0, 13) + "...";
}
graphics.drawString(line2, 80, 230);
} else {
graphics.drawString(title, 80, 150);
}
// 绘制人名
Font f1 = new Font("黑体", Font.BOLD, 100);
graphics.setFont(f1);
// 字体颜色
graphics.setPaint(new Color(255, 255, 255));
// 文字位置
graphics.drawString(name, 80, 340);
// 绘制人物信息
String tip1 = "项目经理";
String tip2 = "手机号: "+ phone;
String tip3 = "职工号: " + str;
graphics.setColor(new Color(255, 255, 255));
Font f2 = new Font("黑体", Font.PLAIN, 47);
graphics.setFont(f2);
graphics.drawString(tip1, 80, 450);
graphics.drawString(tip2, 80, 600);
graphics.drawString(tip3, 80, 700);
graphics.setColor(new Color(37, 39, 55));
Font f3 = new Font("黑体", Font.PLAIN, 56);
graphics.setFont(f3);
// 准备一个二维码文字说明
String tipbottom = "请使用喜猫猫APP扫码";
graphics.drawString(tipbottom, 255, 1680);
String path = ShareImageUtil2.class.getClassLoader().getResource("img").getPath()+File.separator + "bussinessId"+File.separator;
File dir = new File(path);
String random = getRandomNickname(10);
// 转成file类
File file = new File(path+"spuId" + "-"+random+ ".png");
if(!dir.exists()) {
dir.mkdirs();
}
ImageIO.write(sourceImg, "PNG", file);
graphics.dispose();
return file;
}
手机号的json字符串我是用以下方式生成的
Map<String, Object> map = new HashMap<>();
map.put("manager_bind","12365498182");
JSONObject jsonObject = new JSONObject(map);
// 最后调用一下jsonObject的方法即可得到
String phoneBytes = jsonObject.toJSONString();
3、两个工具类
// 生成随机数类
public static String getRandomNickname(int length) {
String val = "";
Random random = new Random();
for (int i = 0; i < length; i++) {
val += String.valueOf(random.nextInt(10));
}
return val;
}
// 图片转base64格式类
public static String imgToBase64(File file) throws IOException {
Base64.Encoder encoder = Base64.getEncoder() ;
InputStream is = new FileInputStream(file);
//String base64 = "data:image/png;base64,"+encoder.encodeToString(IOUtils.toByteArray(is));
String base64 = org.apache.commons.codec.binary.Base64.encodeBase64String(IOUtils.toByteArray(is));
is.close();
return base64;
}
4、测试main方法
流程:先调用生成图片方法传入参数,在主类中调用生成二维码的方法,并将其绘制到图片中,得到图片的file,再调用转base64格式方法将其转换,然后输出即可(传到前端展示)
public static void main(String[] args) throws Exception {
File file = CreatImg.getImage( headerUrl, title, name, phone, str, phoneBytes);
String base64 = "data:image/jpg;base64,"+imgToBase64(file);
System.out.println(base64);
}
5、将打印的结果放到在线工具中测试
测试结果: