微信小程序海报生成图片合成工具类

article/2025/8/21 23:23:05

背景

我目前参与小程序的产品研发,为了方便产品的转发和推广,会对课提供生成海报转发或者分享的功能,前期海报合成这个功能是由项目组的老同事负责开发,后来小程序海报这块功能需要单独做一个功能用于专门根据不同的课程类型来生成海报的功能,很荣幸这个任务交由我开发。编码过程这边就略过了,直接看代码如下所示:

EmojiUtils工具类

package com.xyq.maventest.util;import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**** 
* Project Name:maventest
* <p>emoji标签转换工具类<br> 
*
* @ClassName: EmojiUtils
* @date 2019年1月22日  下午4:29:26
*
* @author youqiang.xiong
* @version 1.0
* @since  
* @see*/
public class EmojiUtils {private static Logger logger = LoggerFactory.getLogger(EmojiUtils.class);/*** 将emoji标签转换成utf8字符集保存进数据库* @param str* @return*/public static String emojiConvert(String str) {String patternString = "([\\x{10000}-\\x{10ffff}\\ud800-\\udfff])";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(str);StringBuffer sb = new StringBuffer();while(matcher.find()) {//	matcher.appendReplacement(sb,"?");try {matcher.appendReplacement(sb,"[[" + URLEncoder.encode(matcher.group(1),"UTF-8") + "]]");} catch(UnsupportedEncodingException e) {logger.error("emojiConvert error"+ e.getMessage());return str;}}matcher.appendTail(sb);logger.debug("emojiConvert " + str + " to " + sb.toString() + ", len:" + sb.length());return sb.toString();}/*** 还原utf8数据库中保存的含转换后emoji表情的字符串* @param str* @return*/public static String emojiRecovery(String str) {if(StringUtils.isEmpty(str)){return "";}try{String patternString = "\\[\\[(.*?)\\]\\]";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(str);StringBuffer sb = new StringBuffer();while(matcher.find()) {try {matcher.appendReplacement(sb, URLDecoder.decode(matcher.group(1), "UTF-8"));} catch(UnsupportedEncodingException e) {logger.error("emojiRecovery error"+ e.getMessage());return "";}}matcher.appendTail(sb);logger.debug("emojiRecovery " + str + " to " + sb.toString());return sb.toString();}catch (Exception e){logger.error("emojiRecovery error",e);}return str;}}

ImageUtils 工具类

核心代码如下:

/**** 
* Project Name:wechat-management-util
* <p>各种海报合成图片工具类<br> 
*
* @ClassName: ImageUtils
* @date 2019年1月22日  下午3:52:43
*
* @author youqiang.xiong
* @version 1.0
* @since  
* @see*/
public class ImageUtils {private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);/***** * Project Name: wechat-management-util* <p>公开课小程序后台生成分享海报 <br> ** @author youqiang.xiong* @date 2019年1月11日  下午4:28:21* @version v1.0* @since * @param background	* 			背景图* @param poster* 			教师形象图* @param qr* 			二维码图片* @param avatar* 			头像图片* @param font* 			字体* @param nickname* 			昵称* @param courseName* 			课程名称* @param courseTip* 			课程大纲* @return * @throws IOException*/public static BufferedImage createSharePoster(BufferedImage background, BufferedImage poster,BufferedImage qr,BufferedImage avatar,Font font, String nickname,String courseName,String courseTip ) throws  IOException{// 开启抗锯齿RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 使用高质量压缩renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);int height = background.getHeight() * 750 / background.getWidth();// 图片大小BufferedImage img = new BufferedImage(750, height, BufferedImage.TYPE_INT_RGB);// 开启画图Graphics2D g = (Graphics2D) img.getGraphics();try {g.setRenderingHints(renderingHints);// 教师海报图 - 需要将原图进行剪切 剪切后的长度是 750*830BufferedImage teacherImage = cutPic(poster, 158, 0, 750, 830);g.drawImage(teacherImage.getScaledInstance(750,teacherImage.getHeight(), Image.SCALE_FAST), 0, 0, null);// 画底图g.drawImage(background.getScaledInstance(750, height, Image.SCALE_FAST), 0, 0, null);// 画头像if (null != avatar) {g.drawImage(ImageUtils.roundImage(avatar, avatar.getWidth(), avatar.getHeight(), 360).getScaledInstance(45*2, 45*2, Image.SCALE_FAST), 25*2, 603*2, null);}// 画二维码if (null != qr) {g.drawImage(qr.getScaledInstance(70*2, 70*2, Image.SCALE_FAST), 286*2, 591*2, null);}// 设置字体大小font = font.deriveFont(34f);// 设置字体颜色Color color = new Color(55,69,97);g.setColor(color);g.setFont(font);//昵称 nickname = nickname == null ? "" : nickname;nickname = EmojiUtils.emojiRecovery(nickname);if(nickname.length() > 5) {nickname = nickname.substring(0, 5) + "...";}int stringWidth = getWidth(g.getFontRenderContext(), g, nickname);g.drawString(nickname, 84 * 2 , 623 * 2);//画'向您推荐好课' String recommendText = "向您推荐好课";font = font.deriveFont(24f);// 设置字体颜色color = new Color(55,69,97);g.setColor(color);g.setFont(font);g.drawString(recommendText, 84 * 2 +  stringWidth , 623 * 2);// 写课程名称font = font.deriveFont(60.0f);color = new Color(69,75,106);g.setColor(color);g.setFont(font);int courseWidth = getWidth(g.getFontRenderContext(), g, courseName);if(courseWidth >= 334*2) {String c1 = courseName.substring(0, 10);String c2 = courseName.substring(10, courseName.length());int courseHeight = getHeight(g.getFontRenderContext(), g, c1);g.drawString(c1, 21 * 2 , (430 * 2) - 2);g.drawString(c2, 21 * 2 , 420 * 2 + courseHeight + 2);}else {g.drawString(courseName, 21 * 2 , 448 * 2);}//写课程大纲List<String> tipList = Arrays.asList(courseTip.split("\n"));String tip1 = tipList.get(0);if(tip1.length() >= 20) {tip1 = tip1.substring(0, 19) + "...";}String tip2 = tipList.get(1);if(tip2.length() >= 20) {tip2 = tip2.substring(0, 19) + "...";}String tip3 = tipList.get(2);if(tip3.length() >= 20) {tip3 = tip3.substring(0, 19) + "...";}font = font.deriveFont(30.0f);color = new Color(176,153,104);g.setColor(color);g.setFont(font);g.drawString(tip1, 47 * 2 , 494 * 2);g.drawString(tip2, 47 * 2 , 527 * 2);g.drawString(tip3, 47 * 2 , 559 * 2);img = Thumbnails.of(img).scale(1f).outputQuality(1f).asBufferedImage();} catch (IOException e) {throw  new IOException(e.getMessage());} finally {g.dispose();}return img;}
}public static int getWidth(FontRenderContext context, Graphics2D g, String text) {return (int) g.getFont().getStringBounds(text, context).getWidth();}public static int getHeight(FontRenderContext context, Graphics2D g, String text) {return (int) g.getFont().getStringBounds(text, context).getHeight();}public static BufferedImage roundImage(BufferedImage image, int width, int height, int cornerRadius) {BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = outputImage.createGraphics();g2.setComposite(AlphaComposite.Src);g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2.setColor(Color.WHITE);g2.fill(new RoundRectangle2D.Float(0, 0, width, height, cornerRadius, cornerRadius));g2.setComposite(AlphaComposite.SrcAtop);g2.drawImage(image, 0, 0, null);g2.dispose();return outputImage;}public static BufferedImage roundImage(BufferedImage image, int cornerRadius) {return roundImage(image, image.getWidth(), image.getHeight(), cornerRadius);}public static Font getPingFang() {BufferedInputStream bis = null;Font definedFont = null;try {bis = new BufferedInputStream(new FileInputStream("C:\\Users\\youqiang.xiong\\git\\WechatManagement\\wechat-management-parent\\wechat-management-m-web\\src\\main\\resources\\pingfang.ttf"));} catch (FileNotFoundException e) {e.printStackTrace();}try {definedFont = Font.createFont(Font.TRUETYPE_FONT, bis);return definedFont;} catch (FontFormatException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}

pom.xml 新增依赖

	<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency>

编写main方法,测试合成图片

  public static void main(String[] args) {try {BufferedImage bg = ImageIO.read(new File("C:\\Users\\youqiang.xiong\\Desktop\\底图\\make_poster_base.png"));BufferedImage poster = ImageIO.read(new File("C:\\\\Users\\\\youqiang.xiong\\\\Desktop\\\\底图\\\\poster.jpg"));BufferedImage qr = ImageIO.read(new File("C:\\\\Users\\\\youqiang.xiong\\\\Desktop\\\\底图\\\\qr.jpg"));BufferedImage avatar = ImageIO.read(new URL("https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTK4DYtvaMV6YIficQnj2D8CiaabaSAq1kzNZUAZCWn5oGv6n8AnjuYTH3bBqELica2yeKbYiakSUMsQIQ/132"));String nickname = "易幻";String courseName = "做有知识的消费者,过1%的品质生活";String courseTip = "给人看和给人讲的PPT有什么区别?\n为什么用了模板还是很丑为什么用了模板还是很丑为什么用了模板还是很丑?\n如何体现PPT制作的专业性?";BufferedImage img = ImageUtils.createSharePoster(bg, poster, qr, avatar, getPingFang(), nickname, courseName, courseTip);ImageIO.write(img, "jpg", new File("C:\\Users\\youqiang.xiong\\Desktop\\底图\\result5.jpg"));} catch (Exception e) {e.printStackTrace();}}

上面的图片是读取我本地的图片,为了方便大家测试,我也把这几张底图和教师形象图上传,以便大家测试,下载图片到本地后,记得修改main方法中的图片路径

第1张海报底图make_poster_base.png
在这里插入图片描述

第2张教师形象图poster.jpg
在这里插入图片描述

第3张小程序码图片qr.jpg

在这里插入图片描述

图片准备好,运行main方法,在指定目录下会生成合成图片 如下图所示:
在这里插入图片描述

放大图片效果:

在这里插入图片描述

到这里一个完成合成小程序海报图的功能已经完成,还算是比较简单的,只需要根据ui给的设计稿来调整字体大小,颜色,xy坐标,长宽即可。


http://chatgpt.dhexx.cn/article/NF66TgjE.shtml

相关文章

平面设计新手如何用PS制作出一张合成海报

本文由:“学设计上兔课网”原创,图片素材来自网络,仅供学习分享 平面设计新手如何用PS制作出一张合成海报?本期教程给大家制作一张关于VR战争合成海报,从合成海报来讲我们要做到以下几点: 创意部分:如何通过创意表现产品功能或其他想要表现的点, 有了创意找到合适的…

小程序画布合成二维码海报图,并保存到相册

小程序画布合成二维码海报图&#xff0c;并保存到相册 实现效果如下图&#xff1a; 步骤分析 1&#xff0c;先获取需要合成的海报和二维码。 2&#xff0c;获取图片的本地路径&#xff0c;如果图片不是网络连接则不需要此操作。 3&#xff0c;通过手机型号&#xff0c;根据…

拿来就用的Java海报生成器ImageCombiner(一)

背景 如果您是UI美工大师或者PS大牛&#xff0c;那本文一定不适合你&#xff1b;如果当您需要自己做一张海报时&#xff0c;可以立马有小伙伴帮您实现&#xff0c;那本文大概率也不适合你。但是&#xff0c;如果你跟我一样&#xff0c;遇上到以下场景&#xff0c;最近公司上了不…

ps海报合成教程_怎样合成创意环保海报图片的PS教程

效果图合成的非常不错&#xff0c;作者用虚实结合的方法来表现主题。创作的时候先构思好想要的画面&#xff0c;然后搜集相关素材(没有的素材可以想办法自己拍摄)&#xff0c;然后按自己思路溶图&#xff0c;润色即可。最终效果 一、拖入原素材&#xff0c;素材大家可以在网络上…

如何制作动态海报?教你一招在线合成GIF海报

相信大家在网上都见过静态海报吧&#xff01;那么&#xff0c;当我们想要将静态的海报制作成炫目的动态海报来吸引大众的目光的时候&#xff0c;应该如何在线制作GIF动态海报呢&#xff1f;这时候&#xff0c;大家就可以使用**gif制作**工具&#xff0c;上传图片一键就可以在线…

设计素材|这些创意海报合成,你会发现创意比技术更重要!

是不是各位也同样收到过这样的话&#xff1a;“这次的海报还是缺点创意啊”、“再改改&#xff0c;润润色”&#xff1b; 想创意熬了三天&#xff0c;海报改了无数版&#xff0c;结果领导还是不满意。 随着设计行业竞争的日益激烈 公司对设计师的水平要求越来越高 如果你是…

怎样合成gif海报?手把手教你一键制作动态海报

相信不少新媒体小编们&#xff0c;在工作中会遇到需要自己设计海报的情况。如果是设计一般的静态海报使用一些修图软件就可以制作&#xff0c;但是当我们需要将这些静态海报变成gif动图海报的时候&#xff0c;应该如何制作gif动态图片海报呢&#xff1f;接下来&#xff0c;小编…

PHP使用Grafika合成图片,生成海报图

需求背景&#xff1a; 在小程序上生成海报图&#xff0c;但在保存图片时&#xff0c;只能保存其中的小程序码图片&#xff0c;保存下来的图片过于单调&#xff0c;且无法确认该图片的作用性&#xff0c;所以需要调整为保存一整张海报图。 海报效果图&#xff1a; 需求分析&a…

合成海报的小程序插件-票圈海报

概述 票圈海报 是一个用于生成海报的小程序插件&#xff0c;通过灵活简单的配置(JSON)就可以生成精美的分享海报&#xff0c;适用于小程序的朋友圈分享等营销裂变场景。 可以绘制文字、图片、线条、色块到海报画布&#xff0c;支持设置宽高、透明度、层级甚至圆角等属性。 亮…

PHP 海报二维码合成

组合参数方法&#xff1a; /*** [user_qrcode 参数组合]* param [type] $bgImg [背景图]* param [type] $codeImg [二维码]* param string $name [名称]* param string $remask [备注]* param string $content [描述]* param integer $key [生成二维码名称…

vue两张图片合成一张(海报二维码合成工具)

公司要经常换海报&#xff0c;一个海报要不同的二维码&#xff0c;做一个工具解决一下。 效果图如下 二维码图片的位置和海报大小可以随意调整 直接放代码&#xff1a; <template><div class"all-tool"><div :style"bgStyle" class"…

【Web技术】961- 3分钟搞定海报合成

背景 在推广业务中&#xff0c;常常会遇到合成带二维码海报分享功能&#xff0c;并且为了推广力度&#xff0c;需要同时在APP、WEB、小程序都有此功能加大曝光&#xff0c;各端都需要单独编写&#xff0c;复用能力差&#xff0c;效率低。本身合成海报业务并无难度&#xff0c;在…

如何合成动态海报?手把手教你一键在线合成gif海报

相信大家在平时都见过那种gif动态海报图片吧&#xff01;是不是觉得只有专业的设计师才能制作呢&#xff1f;其实&#xff0c;这种gif动态海报制作起来非常的简单&#xff0c;只需要准备几张图片尺寸相同图文内容不同的图片&#xff0c;再使用**在线动画制作**工具&#xff0c;…

波束形成MATLAB代码

常规的波束形成方法 clc; clear; close all;fs 1000; c 150; N 128; f 100; lambda c / f; d 0.5 * lambda; theta 1: 1: 180; t (0:1:1000-1) / fs;A zeros(1, length(theta)); A(5) 5; A(20) 4; A(25) 5; A(50) 3; % 在这四个方向上有目标 S zeros(length(th…

相移波束形成算法的MATLAB仿真

仿真结果如下&#xff1a; 部分核心程序如下所示&#xff1a; %************************************************************************** % 相移波束形成算法 %************************************************************************** %…

【波束形成】MMSE波束形成,自适应MMSE波束形成以及自适应MBER波束形成

1.软件版本 matlab2013b 2.本算法理论知识 3.部分源码 clc; clear; close all; warning off;SNR_set [0:1:12]; BER 1; nRx 10; nTx 10; frame_length 1000; Bers []; %论文table 2 alpha [0,10,-15,30,-45,50,60,-5…

基于FPGA的波束形成verilog开发

目录 一、理论基础 二、核心程序 三、仿真测试结果 一、理论基础 根据原理可知&#xff0c;整个波束形成的基本结构框图如下图所示&#xff1a; 这里&#xff0c;我们使用的加权函数为&#xff1a; 这个模块&#xff0c;相当于上述结构的&#xff1a; 二、核心程序 timesca…

鲁棒自适应波束形成

鲁棒自适应波束形成 本文是我关于Microphone Arrays Signal Processing Techniques and Applications第五章的整理。 自适应形成其方向性的波束形成器称为自适应波束形成器。它同时进行波束控制和零位控制。然而&#xff0c;在大多数声波束形成器中&#xff0c;只有在目标DOA是…

窄带波束形成——时域与频域常规窄带波束形成

最近学习了一下《最优阵列处理技术》&#xff0c;应老师要求写一个线性均匀水听器阵列的常规波束形成&#xff0c;由于是初学者&#xff0c;写的可能会有点问题&#xff0c;欢迎大家提出修改建议和指导&#xff0c;写这个主要是记录自己的思考&#xff0c;其次是和初学者进行交…

麦克风阵列波束形成

原文转载于&#xff1a;http://blog.csdn.net/shichaog/article/details/74143427 有所修改 感谢作者 波束形成 beamforming 体现的是声源信号的空域选择性&#xff0c;许多传统波束形成方法具有线性处理结构&#xff1b; 波束形成需要考虑三个方面&#xff1a; 1.麦克风…