见效果:

1. 左上角添加头像,带白边

2. 右下角添加二维码

3. 二维码下添加文字

可实现图片圆角处理,设置图片的宽度,描边==

可实现字体添加与样式

(使用原始图片直接不让上传,模糊下内容)

见代码:

/*** Created by michaeltang on 2019/9/19.** 生成合成图片,以流方式返回给前端显示,用于配置生成海报场景* 可以绘制字体和图片,如:二维码,头像,注意元素的添加顺序,后加入的在上面*/public class ImagePainter {/*** 绘制类型:*/public static final String KEY_TYPE = "key_type";/*** 元素类型:FONT、IMAGE、SQUIRE*/public static final String KEY_ELEMENT = "key_content_element";/*** 字体封装类*/public static class FontElement {public int x;public int y;public int fontSize = 16;public Color fontColor;public boolean bold;public int fontWeight;public String content;public FontElement(){}public FontElement(int x, int y, int fontSize, Color fontColor, boolean bold, int fontWeight, String content) {this.x = x;this.y = y;this.fontSize = fontSize;this.fontColor = fontColor;this.bold = bold;this.fontWeight = fontWeight;this.content = content;}}/*** 图像封装样式*/public static class ImageElement {public int x;public int y;public int width;public int height;public boolean round = false;public int borderWidth = 1;public Color borderColor;public Color bkgColor;public String imageUrl;public ImageElement(){}public ImageElement(int x, int y, int width, int height, boolean round, int borderWidth, Color borderColor, Color bkgColor, String imgUrl){this.x = x;this.y = y;this.width = width;this.height = height;this.round = round;this.borderColor = borderColor;this.borderWidth = borderWidth;this.bkgColor = bkgColor;this.imageUrl = imgUrl;}}/*** 元素类型**/public static enum ElementType implements BaseEnum<ElementType, String> {FONT("FONT", "文字"),IMAGE("IMAGE", "图像");private String value;private String displayName;static Map<String, ElementType> enumMap = new HashMap<String, ElementType>();static {for (ElementType type : ElementType.values()) {enumMap.put(type.getValue(), type);}}private ElementType(String value, String displayName) {this.value = value;this.displayName = displayName;}@Overridepublic String getValue() {return this.value;}@Overridepublic String getDisplayName() {return this.displayName;}public static ElementType getEnum(String value) {return enumMap.get(value);}}/*** 生成合成图片,以流方式返回给前端显示,用于配置生成海报场景** @param request* @param response* @param backgroundUrl 大背景图Url* @param elements 元素数组,可以是字体,可以是图片,如二维码,头像,注意元素的添加顺序,后加入的在上面*/public static void getPaintedStream(HttpServletRequest request, HttpServletResponse response,String backgroundUrl, List<HashMap<String, Object>> elements){// 设置相应类型,告诉浏览器输出的内容为图片response.setContentType("image/jpeg");// 设置响应头信息,告诉浏览器不要缓存此内容response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");try {// 将内存中的图片通过流动形式输出到客户端ImageIO.write(paint(backgroundUrl, elements), "JPEG", response.getOutputStream());} catch (Exception e) {}}public static BufferedImage paint(String backgroundUrl, List<HashMap<String, Object>> components) {if(StringUtils.isEmpty(backgroundUrl)) {throw new OpenmoreException("没有指定背景图像");}if(components == null || components.size() == 0) {throw new OpenmoreException("至少在图片指定一个绘制的组件");}BufferedImage bkgImage = readUrlImage(backgroundUrl);for (HashMap map: components) {Object obj = map.get(KEY_TYPE);if(obj == null) {continue;}ElementType type = (ElementType) map.get(KEY_TYPE);if(type == ElementType.FONT) {FontElement font = (FontElement)map.get(KEY_ELEMENT);drawFont(bkgImage, font);} else if(type == ElementType.IMAGE) {ImageElement image = (ImageElement)map.get(KEY_ELEMENT);drawImage(bkgImage, image);}}return bkgImage;}private static void drawFont(BufferedImage bkgImage, FontElement font){Graphics2D g = bkgImage.createGraphics();g.setColor(Color.WHITE);g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);if(font.bold) {g.setFont(new Font("Microsoft YaHei", Font.BOLD, font.fontSize));} else {g.setFont(new Font("Microsoft YaHei", Font.PLAIN, font.fontSize));}g.setColor(font.fontColor);g.drawString(font.content , font.x, font.y);g.dispose();}private static void drawImage(BufferedImage bkgImage, ImageElement img){Graphics2D g = bkgImage.createGraphics();g.setColor(Color.WHITE);g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);BufferedImage image = readUrlImage(img.imageUrl);if(img.round) {// 图片切成是一个圆型int width = img.width - img.borderWidth * 2;Ellipse2D.Double shape = new Ellipse2D.Double(img.x + img.borderWidth, img.y + img.borderWidth, width, width);g.setClip(shape);g.drawImage(image.getScaledInstance(img.width, img.width, Image.SCALE_SMOOTH), img.x, img.y, img.width, img.width, null);g.dispose();// 画白边Graphics2D g2 = bkgImage.createGraphics();g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);Stroke s = new BasicStroke(img.borderWidth * 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);g2.setStroke(s);g2.setColor(Color.WHITE);g2.drawOval(img.x, img.y, img.width, img.width);g2.dispose();} else {g.drawImage(image.getScaledInstance(img.width, img.height, Image.SCALE_SMOOTH), img.x, img.y, img.width, img.height, null);g.dispose();}}private static BufferedImage readUrlImage(String urlString){try {URL url = new URL(urlString);DataInputStream dataInputStream = new DataInputStream(url.openStream());// 读取背景图return ImageIO.read(dataInputStream);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}throw new OpenmoreException("图片生成错误");}
}

Controller测试代码:

{String bkgUrl = "http://source.wenxiaoyou.com/test/WechatIMG43.jpeg";List<HashMap<String, Object>> elements = new ArrayList<>();HashMap<String, Object> map = new HashMap<>();// 添加二维码map.put(ImagePainter.KEY_TYPE, ImagePainter.ElementType.IMAGE);ImagePainter.ImageElement image = new ImagePainter.ImageElement();image.x = 495;image.y = 980;image.width = 170;image.height = 170;image.imageUrl = "http://source.wenxiaoyou.com/image/1568947454861.jpg";map.put(ImagePainter.KEY_ELEMENT, image);elements.add(map);// 添加头像HashMap<String, Object> avatarMap = new HashMap<>();avatarMap.put(ImagePainter.KEY_TYPE, ImagePainter.ElementType.IMAGE);ImagePainter.ImageElement avatar = new ImagePainter.ImageElement();avatar.x = 30;avatar.y = 30;avatar.width = 128;avatar.height = 128;avatar.borderWidth = 2;avatar.round = true;avatar.imageUrl = "http://source.wenxiaoyou.com/test/1568886588882.jpg";avatarMap.put(ImagePainter.KEY_ELEMENT, avatar);elements.add(avatarMap);// 添加文字HashMap<String, Object> map2 = new HashMap<>();map2.put(ImagePainter.KEY_TYPE, ImagePainter.ElementType.FONT);ImagePainter.FontElement font = new ImagePainter.FontElement();font.content = "扫一扫,领取奖品";font.x = 510;font.y = 1170;font.fontColor = new Color(0, 0, 0);map2.put(ImagePainter.KEY_ELEMENT, font);elements.add(map2);ImagePainter.getPaintedStream(request, response, bkgUrl, elements);
}

java 微信海报的实现相关推荐

  1. java 对比两个表的字段的差异_Joolun小程序商城 2.2.2版本上线了——Java微信快速开发平台...

    Joolun是一款基于spring-boot的微信快速开发平台,目前拥有公众号基础版和小程序商城版两个版本.Joolun采用目前流行的前后端分离技术所写,是一款高效.易用的java微信开发框架平台,二 ...

  2. java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解

    文章目录 前言 一.直接上代码 1. 写字方法 2. 换行算法 二. 叙述换行算法 前言 代码都上传到GitHub了,这里仅仅是贴出来主要部分,GitHub传送门:https://github.com ...

  3. 慕课网_《Java微信公众号开发进阶》学习总结

    时间:2017年08月12日星期六 说明:本文部分内容均来自慕课网.@慕课网:http://www.imooc.com 教学源码:http://img.mukewang.com/down/... 学习 ...

  4. java微信公众号开发token验证失败的问题及解决办法

    java微信公众号开发token验证失败的问题及解决办法 参考文章: (1)java微信公众号开发token验证失败的问题及解决办法 (2)https://www.cnblogs.com/beardu ...

  5. 捷微jeewx , 免费开源(java)微信公众账号管家系统发布

    JeeWx, 微信管家平台,简称"捷微". 捷微是一款免费开源的JAVA微信公众账号开发平台.   平台介绍: 一.捷微Jeewx简介 Jeewx是一个开源.高效.敏捷的微信开发平 ...

  6. java 微信退款接口_java版微信和支付宝退款接口

    本文实例为大家分享了java微信退款接口和支付宝退款接口的具体代码,供大家参考,具体内容如下 1.微信退款接口 相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可: /** ...

  7. Java微信公众平台开发--番外篇,对GlobalConstants文件的补充

    转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...

  8. Java微信订单查询

    版权声明:本文首发 http://asing1elife.com ,转载请注明出处. https://blog.csdn.net/asing1elife/article/details/8262004 ...

  9. java微信支付代码_Java微信支付之服务号支付代码示例

    Java微信支付之服务号支付实现,网上的java微信支付sdk和Demo基本上是水的,看着头疼所以我决心自己开始写Java微信支付之公众号支付,多的不说见下面源码,为了方便使用我分别用了两个Servl ...

最新文章

  1. 零起点学算法01——第一个程序Hello World!
  2. javamail gmail
  3. R语言ggplot2可视化:使用scale_y_continous函数自定义指定Y轴的坐标范围以及对应的数值、将坐标轴的数值设置为需要的数据类型(整型、浮点型)
  4. java鼠标样式设置,设置Echarts鼠标悬浮样式
  5. facebook对话链接_并非里程碑! Facebook的100种语言互译模型夸大宣传遭质疑
  6. java分布式api网管关,分布式04-Spring Cloud Zuul Api网关 一
  7. 普通筛法时间界的证明
  8. 马行走路线的测试用例设计
  9. FlexSPI driver用法
  10. SharePoint 2010新体验9 - 内容管理器(Content Organizer)
  11. html+css基础教程入门之CSS 尺寸
  12. html只能用鼠标进行各种操作,鼠标的基本操作有哪些?
  13. 2021上海酵素展暨中国酵素节资讯食用酵素的营养功效及研究进展
  14. 海康威视2020届校园招聘内推(内含内推码)
  15. 数据结构 —— 图解AVL树(平衡二叉树)
  16. 解密QQ号(stl库)
  17. vim操作方式的PDF阅读器 okular
  18. 华硕笔记本k555拆机图解_华硕K751大屏笔记本拆机解析
  19. KVG制作-【Arduino指纹解锁 智能家居系列-01】DIY自制的智能门禁,AS608指纹解锁+红外线遥控解锁。附演示视频。
  20. 【实验1 顺序结构】7-3 sdut-C语言实验-虎子分糖果

热门文章

  1. 使用Git上传项目代码到github
  2. 3D姿态估计:语义图卷积SematicGCN与GAN-RepNet
  3. python3异步task_Python异步编程4:task对象
  4. 校园无线广播-河北赵县职业中心校园无线广播系统方案
  5. JS使用sort进行升序和降序排序
  6. Tina R16开发说明
  7. 内网穿透远程群晖NAS:申请SSL安全证书 4/5
  8. 微信小程序:王者荣耀出装与铭文推荐助手
  9. safeengine虚拟机licence破解手记
  10. 9.29:编写微信的思维导图