简介:
生活和工作中大家是否遇到过需要生成一张完全属于自己的名片或者生成一个自定义的海报?上面展示自己的头像、有自己的简介、自己的二维码及公司的logo等,今天就跟大家分享一下如何通过Java实现自定义生成海报。
准备:
1、准备一张背景图
2、准备头像图片
实现:
Java后端实现画布绘制图像需要使用到java.awt包下面的BufferedImage
1、首先先创建一个背景图片输入流
FileInputStream fis = new FileInputStream(new File(""E:\\poster\\back.png""));
2、创建背景图片对象
Image srcImg = ImageIO.read(fis);
3、根据背景图片的宽高创建画布
BufferedImage bufferedImage = new BufferedImage(
//宽度
srcImg.getWidth(null),
//高度
srcImg.getHeight(null),
//图片类型
BufferedImage.TYPE_INT_RGB);
4、创建2D画笔对象
Graphics2D g = bufferedImage.createGraphics();
5、设置画布背景
g.drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0,null);
6、开始绘制
//绘制头像
g.drawImage(transferImgForRoundImgage(avatarDir), 278, 76, 196, 196, null);
//绘制字符串(简介、描述等)
Graphics2DUtils.drawString(g, Color.decode("#000000"), new Font("微软雅黑", Font.BOLD, 48), nickName, 0, 338, width, 12, 5, true);
//绘制二维码
g.drawImage(ImageIO.read(qrCodeImg), 202, 654, 348, 348, null);
7、处理画作
g.dispose();
8、得到输出流
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", os);
项目中有用到生成二维码的功能,使用的是谷歌推出的二维码解析和生成的开源库,项目地址为https://github.com/zxing/zxing,具体使用方法将在下片文章中给大家分享。
具体代码:
public String createPoster(String nickName,String idNum,String description,String avatarDir,String qrcodeDir) throws Exception {
String resourcePath = PosterUtils.class.getResource("/image/").getPath();
long nowTime = System.currentTimeMillis();
File qrCodeImg = new File(qrcodeDir);
File fileBg = new File("F:\\poster\\back.png");
//1、背景图片输入流
FileInputStream fis = new FileInputStream(fileBg);
//2、背景图片对象
Image srcImg = ImageIO.read(fis);
//3、创建画布,根据背景图片的宽高
BufferedImage bufferedImage = new BufferedImage(
//宽度
srcImg.getWidth(null),
//高度
srcImg.getHeight(null),
//图片类型
BufferedImage.TYPE_INT_RGB);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
System.out.println("width:"+width);
System.out.println("height:"+height);
//4、得到2d画笔对象
Graphics2D g = bufferedImage.createGraphics();
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//5、设置画布背景
g.drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0,null);
//6、```````````开始作画```````````
/*Font rewardFirstFont = new Font("PingFang SC Bold", Font.PLAIN, 24);
Font rewardLastFont = new Font("PingFang SC Bold", Font.PLAIN, 48);*/
//头像图片
if(StringUtils.isNotBlank(avatarDir)){
//URL avatarUrl = new URL(avatarDir);
g.drawImage(transferImgForRoundImgage(avatarDir), 278, 76, 196, 196, null);
}
//昵称
Graphics2DUtils.drawString(g, Color.decode("#000000"), new Font("微软雅黑", Font.BOLD, 48), nickName, 0, 338, width, 12, 5, true);
//ID号
Graphics2DUtils.drawString(g, Color.decode("#999999"), new Font("微软雅黑", Font.PLAIN, 32), idNum, 0, 408, width, 12, 5, true);
//简介
if(StringUtils.isNotBlank(description)){
Graphics2DUtils.drawString(g, Color.decode("#000000"), new Font("微软雅黑", Font.PLAIN, 28), description, 0, 526, width, 20, 5, true);
}
//二维码图片
g.drawImage(ImageIO.read(qrCodeImg), 202, 654, 348, 348, null);
// ```````````结束作画```````````
//7、处理画作
g.dispose();
//8、得到输出流
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", os);
//9、转成base64编码前端可以直接显示,也可转换成其它形式比如文件
String encodeStr = Base64.getEncoder().encodeToString(os.toByteArray());
//保存为图片文件
FileUtils.writeByteArrayToFile(new File("D:/poster/" + nowTime + ".jpg"), os.toByteArray());
//10、关闭输入输出流
fis.close();
os.close();
//qrCodeImg.delete();
//petImg.delete();
return "D:/poster/" + nowTime + ".jpg";
}
/**
* 将图片处理为圆形图片
* 传入的图片必须是正方形的才会生成圆形 如果是长方形的比例则会变成椭圆的
*
* @param url
* @return
*/
public static BufferedImage transferImgForRoundImgage(String url){
BufferedImage resultImg = null;
try {
if (StringUtils.isBlank(url)) {
return null;
}
BufferedImage buffImg1 = ImageIO.read(new URL(url));
resultImg = new BufferedImage(buffImg1.getWidth(), buffImg1.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = resultImg.createGraphics();
Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, buffImg1.getWidth(), buffImg1.getHeight());
// 使用 setRenderingHint 设置抗锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
resultImg = g.getDeviceConfiguration().createCompatibleImage(buffImg1.getWidth(), buffImg1.getHeight(),
Transparency.TRANSLUCENT);
//g.fill(new Rectangle(buffImg2.getWidth(), buffImg2.getHeight()));
g = resultImg.createGraphics();
// 使用 setRenderingHint 设置抗锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setClip(shape);
g.drawImage(buffImg1, 0, 0, null);
g.dispose();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
return resultImg;
}
扩展:
根据以上实现逻辑可以进行扩展,将方法抽象出来,减少代码及模板重复开发量,可以制作海报、名片、广告图、通告图等等。