618 年中促销即将来临,很多公司都会通过海报来宣传自己的促销方案,通常情况下海报由设计团队基于 PS、Sketch 等工具创作,后期若想替换海报文案、商品列表等内容则需打开原工程进行二次创作,修改门槛高且不够便捷。由于公司的促销列表每日上新,急需一种简单快捷的方式来修改并生成新的海报,以及公司小程序图片分享获客需要海报分享并进行引流,因此,调研了一些云端图片合成并生成海报的方案;
在调研中发现了 veImageX 这款产品可以支持此能力,veImageX 是火山引擎推出的一款的图片解决方案,具备存储、分发、图像处理等完整的云 + 端一体化能力,其下的创意魔方具备图片、文字、二维码、背景等元素的合成,支持在线编辑模板 + 云端生成图片的能力,并提供了完善的 OpenAPI 可用于搭建自己的平台。
因此,本文基于 veImageX 搭建一个海报生成平台,目标是能够灵活替换其中的文案、图片等元素,支持预览和一键导出图片,本文重点记录一下操作的过程;
额外需要提一下,目前veImageX还有一些特惠促销,生成海报所需的流量和存储资源包均有较大折扣,比如可1元购 100GB流量 或 50GB存储,也可以按需采购;
新建样式

3. 注意:请选择服务状态为正常的服务,可在服务管理页面查找服务状态;

创作模板
veImageX 支持图片、文字、二维码、背景四种类型的元素,能够满足绝大多数的创作场景。可参考 帮助文档,以下补充几点我的经验:
2. 海报底图通常是固定不变的,建议将其设置为背景元素,背景元素为不可变元素,可防止创作过程中的误操作;

5. 二维码有文字和链接两种类型,注意不要选错;
保存模板
在编辑过程中样式会自动保存,为防止意外发生,退出前可点击左上角(或 Command + S / Ctrl + S)手动保存;
点击右上角预览按钮,预览云端渲染效果;
每个样式模板都有唯一的 StyleId,创作完成后可在“我的样式”页面查看并保存。

项目基于 Next.js 搭建,主要依赖项如下:
框架:Next.js
上传 SDK:tt-uploader
OpenAPI SDK:@volcengine/openapi
如有需要可基于该 项目模板 搭建自己的海报平台。
项目中依赖 veImageX 提供的 OpenAPI 来提交模板参数并拿到合成图片的 URL,本文借助 @volcengine/openapi 访问 OpenAPI,SDK 依赖用户的 AK、SK (可在密钥管理页面获取)生成签名用于鉴权。以下是项目中用到的两个 API:
请求方式: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: {},
});
请求方式: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 上使用;
整体效果不错~~
文章为原创文章,若有侵权请联系;
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些
有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.