(干货)基于 veImageX 搭建海报生成平台 -- 附源码
前言
618 年中促销即将来临,很多公司都会通过海报来宣传自己的促销方案,通常情况下海报由设计团队基于 PS、Sketch 等工具创作,后期若想替换海报文案、商品列表等内容则需打开原工程进行二次创作,修改门槛高且不够便捷。由于公司的促销列表每日上新,急需一种简单快捷的方式来修改并生成新的海报,以及公司小程序图片分享获客需要海报分享并进行引流,因此,调研了一些云端图片合成并生成海报的方案;
在调研中发现了 veImageX 这款产品可以支持此能力,veImageX 是火山引擎推出的一款的图片解决方案,具备存储、分发、图像处理等完整的云 + 端一体化能力,其下的创意魔方具备图片、文字、二维码、背景等元素的合成,支持在线编辑模板 + 云端生成图片的能力,并提供了完善的 OpenAPI 可用于搭建自己的平台。
因此,本文基于 veImageX 搭建一个海报生成平台,目标是能够灵活替换其中的文案、图片等元素,支持预览和一键导出图片,本文重点记录一下操作的过程;
额外需要提一下,目前veImageX还有一些特惠促销,生成海报所需的流量和存储资源包均有较大折扣,比如可1元购 100GB流量 或 50GB存储,也可以按需采购;
开通服务
- 找到他们的官网,点击这里可以直接进去,火山引擎,开通 veImageX;
- 创建服务并绑定域名,这一步可以参考官方文档,创建服务可以理解为创建一个存储空间,绑定域名,理解为需要一个访问的地址;
- 进入 veImageX创意魔方 页面,根据提示开通该项能力。
创作模板
新建样式
- 点击新建样式-选择服务-填写名称-设置尺寸;
- 注意:请选择服务状态为正常的服务,可在服务管理页面查找服务状态;
创作模板
veImageX 支持图片、文字、二维码、背景四种类型的元素,能够满足绝大多数的创作场景。可参考 帮助文档,以下补充几点我的经验:
海报底图通常是固定不变的,建议将其设置为背景元素,背景元素为不可变元素,可防止创作过程中的误操作;
图片、文字、二维码都是可替换元素,建议设置有意义的元素名称;
二维码有文字和链接两种类型,注意不要选错;
创建样式时可根据底图尺寸设置样式尺寸,编辑过程中底图过长或图片尺寸不符合要求,可使用图片裁剪能力;
保存模板
在编辑过程中样式会自动保存,为防止意外发生,退出前可点击左上角(或 Command + S / Ctrl + S)手动保存;
点击右上角预览按钮,预览云端渲染效果;
每个样式模板都有唯一的 StyleId,创作完成后可在“我的样式”页面查看并保存。
项目搭建
项目基于 Next.js 搭建,主要依赖项如下:
框架:Next.js
上传 SDK:tt-uploader
OpenAPI SDK:@volcengine/openapi
如有需要可基于该 项目模板 搭建自己的海报平台。
访问 OpenApi
项目中依赖 veImageX 提供的 OpenAPI 来提交模板参数并拿到合成图片的 URL,本文借助 @volcengine/openapi 访问 OpenAPI,SDK 依赖用户的 AK、SK (可在密钥管理页面获取)生成签名用于鉴权。以下是项目中用到的两个 API:
GetImageStyleResult
请求方式:HTTP POST
接口描述:提交合成任务,获取合成后的图片 URL,参数如下:
请求参数:
参数 | 类型 | 参数类型 | 是否必填 | 描述 |
---|---|---|---|---|
Action | String | Query | 是 | 接口名:取值GetImageStyleResult |
Version | String | Query | 是 | 版本号:2018-08-01 |
ServiceId | String | Query | 是 | 服务ID,用于计量计费和渲染结果的存储。服务ID和样式绑定的服务ID均需属于调用账号,否则无权限处理 |
StyleId | String | JSON | 是 | 待渲染的样式ID |
Params | JSON Map | JSON | 否 | 样式中动态要素的取值。Key为String类型,取值要素ID;Value为String类型,取值动态要素的值(图片地址、文本/二维码内容) |
OutputFormat | String | JSON | 否 | 渲染结果编码格式。可选取值:JPEG、WEBP、PNG、HEIC。默认使用样式中定义的格式 |
OutputQuality | Integer | JSON | 否 | 渲染结果编码质量参数。默认使用样式中定义的质量参数 |
返回参数:
参数 | 类型 | 描述 |
---|---|---|
ResUri | String | 渲染结果的URI |
RenderDetail | JSON Array | 渲染详情 |
RenderDetail:
参数 | 类型 | 描述 |
---|---|---|
Element | String | 渲染失败的要素ID |
ErrMsg | String | 渲染失败的原因 |
代码示例:
import { imagex } from '@volcengine/openapi';
const imagexService = imagex.defaultService;
imagexService.setAccessKeyId("xxx");
imagexService.setSecretKey("xxx");
const GetImageStyleResult = imagexService.createUrlEncodeAPI('GetImageStyleResult', {
method: 'POST',
contentType: 'json',
queryKeys: ['Action', 'Version', 'ServiceId']
});
const result = await GetImageStyleResult({
ServiceId: '',
StyleId: '',
Params: {},
});
GetImageStyleDetail
请求方式:HTTP GET
接口描述:根据 StyleId 获取样式详情,用于获取可替换的元素
请求参数:
参数 | 类型 | 参数类型 | 是否必填 | 描述 |
---|---|---|---|---|
Action | String | Query | 是 | 接口名:取值GetImageStyleDetail |
Version | String | Query | 是 | 版本号:2018-08-01 |
StyleId | String | Query | 是 | 样式ID |
返回参数:
参数 | 类型 | 描述 |
---|---|---|
Style | JSON Object | 样式结构 |
上传图片
样式模板中存在可被替换的图片元素,因此平台需要支持本地上传图片的能力。项目中基于 tt-uploader 实现上传功能。
上传 SDK 在端上访问 OpenAPI 获取上传地址,为防止端上泄露 AK/SK,因此需要由服务生成临时的 Token 下发到端上,SDK 基于临时 Token 生成签名访问 OpenAPI。项目中基于 @volcengine/openapi SDK 签发临时的 Token,示例代码如下:
import { imagex } from '@volcengine/openapi';
const imagexService = imagex.defaultService;
imagexService.setAccessKeyId('xxx'); //这里是要填写ak和sk的地方;
imagexService.setSecretKey('xxx');
const token = imagexService.GetUploadAuth({
serviceIds: [], // 仅允许上传到指定的服务ID,若无此限制,传递空数组即可
expire: 5 * 60 * 1000, // 临时密钥过期时间(单位为毫秒),默认为1小时
});
项目部署
项目基于 Next.js 开发,因此部署在 Vercel 上,Vercel 支持一键部署,且部署后自动生成预览 URL。由于部署流程比较简单且网上教程很多,这里不再赘述,可参考官方文档。
效果
平台效果如下,输入替换文案、图片等元素,点击预览即可查看合成后的新海报,支持下载到本地。可参考平台代码。
代码已经放到github上了,如果有需要的朋友,可以直接git 上使用;
整体效果不错~~
文章为原创文章,若有侵权请联系;
(干货)基于 veImageX 搭建海报生成平台 -- 附源码的更多相关文章
- 开源方案搭建可离线的精美矢量切片地图服务-8.mapbox 之sprite大图图标文件生成(附源码)
项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...
- 基于Redis缓存的Session共享(附源码)
基于Redis缓存的Session共享(附源码) 在上一篇文章中我们研究了Redis的安装及一些基本的缓存操作,今天我们就利用Redis缓存实现一个Session共享,基于.NET平台的Seesion ...
- 一文详解如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
雷锋网按:本文作者陆池,原文载于作者个人博客,雷锋网已获授权. 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实例,这个星期就用 ...
- 基于jQuery左右滑动切换特效 附源码
分享一款基于脚jQuery左右滑动切换特效.这是一款鼠标点击左右箭头按钮图片滚动切换,鼠标移到图片上显示透明边框特效. 效果图如下: 废话不多说,代码奉上! html代码: <div ...
- 教你搭建SpringMVC框架( 附源码)
一.项目目录结构 二.SpringMVC需要使用的jar包 commons-logging-1.2.jar junit-4.10.jar log4j-api-2.0.2.jar log4j-core- ...
- Java基于POI实现excel任意多级联动下拉列表——支持从数据库查询出多级数据后直接生成【附源码】
Excel相关知识点 (1)名称管理器--Name Manager [CoderBaby]首先需要创建多个名称(包含key及value),作为下拉列表的数据源,后续通过名称引用.可通过菜单:&quo ...
- MyBatis model、xml、mapper 自动生成,附源码
Mybatis 代码自动生成 model.xml.mapper 代码结构图 代码地址 https://github.com/shootercheng/codegen 需要修改的地方见 readme
- 教你搭建SpringSecurity3框架(附源码)
源码下载地址:http://pan.baidu.com/s/1qWsgIg0 一.web.xml <?xml version="1.0" encoding="UTF ...
- 一个基于jQuery写的弹窗效果(附源码)
最近项目中频繁遇到需要弹出窗口的功能,一直使用浏览器默认的Alert和Confirm弹窗,感觉视觉效果不是那么好,而从网上下载的话又找不到合适的,找到的话有些也是十分臃肿,有时候感觉学习配置的功夫自己 ...
随机推荐
- ubantu系统之 lunch时报错:no such file /....../.lunchrc
no such file /....../.lunchrc 出现时: 使用 source build/envsetup.sh 执行完后 再用lunch
- FastAPI(六十六)实战开发《在线课程学习系统》接口开发--用户注册接口开发
在前面我们分析了接口的设计,那么我们现在做接口的开发. 我们先去设计下pydantic用户参数的校验 from pydantic import BaseModel from typing import ...
- 阿里云申请SSL证书 并部署到SpringBoot项目
前提 有一台阿里云的服务器(安装了java环境) 有已经备案的域名,并且域名绑定上面的服务器 申请SSL证书 申请教程:https://blog.csdn.net/yunweifun/article/ ...
- Java 18 新功能介绍
文章持续更新,可以关注公众号程序猿阿朗或访问未读代码博客. 本文 Github.com/niumoo/JavaNotes 已经收录,欢迎Star. Java 18 在2022 年 3 月 22 日正式 ...
- NodeJs学习日报day5——导入模块
const { match } = require("assert") function dateFormat(dataStr) { const dt = new Date(dat ...
- SSM阶段学习-mybatis第一天
首先今天我尝试了使用IDEA软件链接数据库,创建数据库,创建表. 在pom文件下导入maven坐标 [<?xml version="1.0" encoding="U ...
- 2021.08.09 P5018 对称二叉树(树形结构)
2021.08.09 P5018 对称二叉树(树形结构) [P5018 NOIP2018 普及组] 对称二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 求一棵子树,关 ...
- ubuntu16.04安装MATLAB R2017b步骤详解(附完整文件包)
摘要:介绍在ubuntu16.04中从下载到安装成功的完整步骤.本文给出MATLAB R2017b(Linux系统)的完整安装包百度云盘下载地址,逐步介绍一种简单易行的安装方法,在桌面创建快捷方式,最 ...
- golang /js index 转换excel字母表头
Golang 1 package main 2 3 import "fmt" 4 5 func main() { 6 var Letters = []string{"A& ...
- [AcWing 822] 走方格
点击查看代码 #include<iostream> using namespace std; int n, m, ans = 0; void dfs(int x, int y) { if ...