随着AIGC技术的快速发展,天猫新品创新(TMIC)业务积极拥抱这一浪潮,推出了画布引擎以赋能商家在新品设计环节中的创作需求。画布引擎是一个基于Canvas的UI框架,通过整合前端渲染能力和AIGC算法模型接口,为用户提供了一套操作画布元素的底层能力。
画布引擎的设计兼顾了专业性和易用性,界面简洁友好,适合普通用户快速上手。其技术实现基于Konva库,通过定义画布协议实现了对画布状态的抽象描述,并支持撤销、重做、另存为等功能。此外,画布引擎还提供了开放组件和SDK,便于不同业务快速接入或定制化开发。目前,画布引擎已在TMIC和产业AI平台上成功应用,并将持续引入新功能以满足更多业务需求。
自2022年以来,随着DALL-E 2、Midjourney、Stable Diffusion等项目的公开发布,极大地降低了普通人使用AIGC生成图片的技术门槛。面对这波AI浪潮,各个团队都开始积极拥抱AIGC,其中也包括天猫新品创新业务。天猫新品创新中心(Tmall Innovation Center,简称TMIC)依托阿里大数据、AI算法、生态共建,全方面赋能企业商品研发创新,在新品全生命周期内(市场洞察->新品设计->新品测试->新品上市),提供一站式解决方案。由于新品设计环节对创作的潜在需求和AIGC的能力不谋而合,TMIC主动开始探索利用AIGC赋能商家的业务场景。
在开始探索AIGC落地的阶段,业务同学和技术同学从各自的专业角度出发,相对独立地建设了多个场景。这些场景某种程度上依赖一些同质化的底层能力,因此引起了重复工作。为了避免后续出现类似问题并提高研发效率、缩短业务落地周期,我们收集了已经实现的场景下的功能,发现它们都依赖前端提供的画布能力以及算法提供的AI能力。于是我们将这些共性的底层能力进行了抽象,最终沉淀为了现在的画布引擎。
画布引擎是一个帮助用户轻松使用AIGC能力的UI框架。它以Canvas画布为核心,提供了一套操作画布元素的底层能力,通过调用特定的AIGC算法模型接口,最终将画布内容转化成符合期望的商品图和模特图。画布引擎目前已实现了多种AIGC工具以及纯前端画布功能,并且赋能了TMIC、产业AI平台上的多个业务场景。
如何实现画布引擎
▐ 产品说明
在产品设计阶段,我们调研了两类最常见的画布引擎。一类以stable-diffusion-webui(下图1)为代表,它们具备完善的AIGC调节项,但是界面复杂,对于普通用户来说不够友好;另一类以美图秀秀(下图2)为代表,在提供精美界面的同时隐藏了高级参数选项,降低了用户的使用门槛。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
由于我们的业务面向商家用户,因此在思考画布引擎的定位时,我们在专业和简洁之间选择了后者。最终,我们实现的画布引擎的界面如下图。它的大部分功能参考了美图秀秀,包括文件管理、智能画面调节、智能画笔消除、添加滤镜、添加文字、添加边框、智能背景、添加素材、智能水印等。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
文件管理主要支持从本地上传图片并替换画布背景图以及下载画布背景图到本地(下图1)。另外画布引擎还提供了多种模板图方便用户快速套用(下图2)。
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
智能画面调节支持图像裁剪、延展、清晰度调节、局部换色。图像裁剪(下图1)允许用户自由设置裁剪区域并去除区域外的内容;延展功能(下图2)支持按比例延展图片,并通过AIGC能力补充延展后的空白区域;清晰度调节(下图3)将图片高清化或压缩成用户选择的清晰度;局部换色(下图4)通过AIGC能力将图片目标区域替换为特定的颜色。
智能画笔消除是最常见的AIGC功能:用户首先在画布上涂抹待擦除区域(下图1),AI模型就会消除区域内的物体(下图2)。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
智能背景支持将一张商品图生成白底图下图1和透明底图。智能水印既可以为物料添加品牌logo(下图1),也可以将花纹平铺在服饰上(下图2)。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
除了上述基于AIGC实现的能力外,画布引擎还提供了一系列纯前端实现的功能,包括添加滤镜(下图1)、添加文字(下图2)和更多装饰性元素。
|
|
图1 | 图2 |
▐ 技术实现
我们的目标不止于实现一个画布引擎,还希望通过开放组件和SDK,帮助不同业务快速接入甚至定制自己的画布引擎。为此,我们进行了如下架构设计。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
画布组件作为基础设施,提供了纯前端的渲染和交互能力。基于单一职能原则,我们希望画布能力与AIGC能力解耦,专注于内容渲染的部分。这样一来,画布既可以作为进一步实现官方画布引擎的底层能力,也可以作为组件提供给不需要AIGC能力而只需要画布渲染能力的外部业务场景。首先,我们定义了一套画布协议。它是一个json对象,包含宽高等基础设置、背景图/背景色等常规属性以及渲染在画布上的原子组件等内容。画布协议提供了对画布状态的抽象描述,不仅可以用来快速渲染、更新画布,还可用于实现画布的撤销、重做、另存为和再次编辑等功能。关于画布协议的示例可以参考附录。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
接着,我们选择Konva用于渲染画布。Konva 是一个用于创建复杂的canvas图形和动画的JavaScript库。,为渲染和操作画布元素提供了一套完善的SDK,且支持React语法。基于Konva提供的一系列基本元素(线条、圆圈等),我们实现了多个具有交互能力的原子组件,例如可以自由控制轨迹的笔刷和橡皮,以及通过在画布上拖拽来新增特定尺寸和比例的多边形等。最终,画布协议作为参数被传入组件,通过画布引擎将指定的原子组件渲染在画布上。使用画布组件时,只需传入初始协议和协议更新函数,即可实现双向数据绑定:从外部改变协议内容可以触发画布重绘,而与画布元素的交互行为也会实时调用传入的更新函数。一个完整的画布工作过程如上图所示。
画布组件有多种使用场景。纵向,它可以用于实现官方画布引擎和业务自定义画布引擎;横向,它可以作为一个纯前端组件提供给其他业务嵌入到自己的项目中,例如产业AI平台的数据标注场景就借助画布中的矩形原子组件实现了通过框选商品图元素进行数据标注的功能。
围绕着画布组件,我们进一步建设了画布引擎能力。主要实现了1. 和画布交互的用户界面和2. 调用AIGC模型能力并将生成结果反映到画布上。
首先,同样有一套用于描述画布引擎状态的协议。它描述了一个完整的画布引擎结构,包含顶部栏、底部栏、工具栏等功能模块。具体示例可参见附录。另外,由于画布是画布引擎重要组成部分,因此我们将画布协议也整合到了画布引擎协议里面。基于画布引擎协议,用户可以定制画布引擎的具体展示,例如隐藏/显示顶部栏或底部栏,以及工具栏中包含哪些工具和这些工具按钮的排布等。
其次,我们实现了一个工具箱,包含一系列AIGC/前端画布工具。关于每个工具的功能介绍可以参考上面的产品说明章节。我们为每个工具都实现了一个工具面板,上面展示了工具的使用步骤以及各项参数调节按钮,例如智能擦除工具面板上有滑块可以对橡皮擦尺寸进行调节,并实时地更新画布引擎协议里的相应数值,最终反映在涂抹在画布中的线条的粗细上。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
进一步的,我们可以在这些工具能力之上实现一个GUI。但是在此之前,我们额外设计了一个视图模型层,它主要负责协议状态的维护以及暴露状态和事件到下游的GUI层。这些暴露出来的状态数据以及状态管理API既可以用于实现官方GUI,也便于其他业务实现自定义的GUI,上图展示了实现自定义GUI的代码示例。GUI的建设重点是工具面板。工具面板承载了两个功能:1. 调节工具的内部参数,以及对于依赖AIGC模型的工具而言,还需要 2. 透出模型调用按钮,并将模型生成结果更新到画布协议中以驱动画布重绘。
最后,和画布组件一样,我们也实现了画布引擎的开放能力。我们将官方画布引擎变成了一个组件,这意味着它同样可以被内嵌到外部项目代码中,并通过画布引擎协议实现双向数据绑定。另外,我们也提供了实现画布引擎所需的SDK和协议规范,供开发实现定制化的画布引擎规范,下图展示了我们的业务的定制化GUI界面。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
画布引擎的开放能力依托于质量体系来保障自身的稳定性,因此我们对这方面格外重视。除了通过不断重构来持续优化代码结构以降低潜在的日常迭代带来的故障风险外,我们还在单元测试方面做了大量工作。
目前画布引擎的单测覆盖率在85%以上,如下图所示。我们针对画布引擎的实际应用情况,设置了包括画布引擎组件测试和画布组件测试在内的5个测试场景,编写了35条测试用例,涵盖了初始化流程、画布原子组件实现、画布元素形变&拖拽保护、画布引擎工具实现、GUI交互、撤销重做功能等在内的核心逻辑。随着测试体系的持续建设和画布引擎功能的不断丰富,我们的用例数和覆盖率预计会得到进一步提升。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
具体实现上,我们选择了Jest + React Testing Library来搭建单测框架。Jest是一个由 Facebook 开发的 JavaScript 测试框架,它支持多种断言库(如 Jest 自带的断言库、Expect.js 等),并且内置了代码覆盖率报告、模拟函数等功能。React Testing Library专注于帮助开发人员测试应用程序的行为而不是实现细节。通过从用户角度来编写测试,即模拟用户交互,并检查应用是否正确响应这些交互。单测系统的文件结构如下图1所示。从上到下,components目录用于存放一些测试用的临时组件;datas存放测试用的数据,包括画布引擎协议快照和mock后端接口请求的数据;describes存放的是我们编写的各种测试场景和测试用例;utils存放测试工具,包括用于比较协议快照的工具函数;setupTests.js文件可以在运行任何测试之前执行一些初始化代码,包括设置一些全局的 mock对象;jest.config.js 是 Jest 测试框架中的一个配置文件,用于自定义 Jest 的行为,包括测试运行时所处的环境(jsdom/node)、设置单测覆盖率统计口径等。与常规的前端应用不同的是,画布引擎依赖画布能力,但是Jest提供的快照能力只用于记录html结构,而无法记录画布内容,这给我们带来了一定的挑战。幸运的是,由于我们的底层设计是让画布基于一套协议来进行渲染,而这套协议正好可以作为画布内容的快照来被比较,因此我们利用这一点绕过了这个障碍。所以在单元测试中,我们主要用比较了单测运行后的协议内容是否符合预期的协议快照(再配合一部分的html快照对比)来作为测试是否通过的依据。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
进入到describes目录下,每个测试场景的目录结构保持一致,以上图2为例。其中index.test.tsx是单测场景的入口文件,Jest在启动时会遍历test目录下的所有index.test.tsx并依次执行。index.test.tsx作为待执行的测试用例集合的索引,内容如下图1所示。在 Jest 测试框架中,describe 是一个全局函数,用于组织测试代码和定义测试场景及其子场景(describe允许嵌套)。每个 describe 块可以包含多个 test 函数,这些函数定义了具体的测试案例。另外jest提供了beforeEach/afterEach/beforeAll/afterAll全局函数,用于定义在测试用例前后需要执行的初始化代码,通常包括设置测试环境、准备数据或者重置某些状态等操作,具体内容被放在functions函数下,一个beforeEach函数的内容如下图2所示。它执行了模拟图片加载、渲染待测试组件、定义快照比较函数、向全局环境注入测试依赖变量和方法等工作,以保障每条单测的顺利执行。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
| ' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
|
图1 | 图2 |
最后,具体到每条测试用例中,主要做两件事:1. 模拟用户行为 2. 验证画布引擎状态是否符合预期。上图2展示了测试智能擦除工具的用例。我们首先通过dom事件机制模拟了用户行为,打开擦除工具并在画布上涂抹了擦除区域。在验证擦除区域出现在了画布上之后,用例进一步验证了擦除结果返回后的画布引擎协议快照和预期快照数据是否吻合,以此判断是否通过测试。由于画布引擎暂未开源,因此只在这一章节简单阐述下内部业务场景下使用过程。首先内部用户可以通过命令安装npm包。另外我们建立了一个官方文档库,结合演示用例,我们详细介绍了画布组件、画布引擎组件以及每个画布引擎API的使用方法,供开发同学查阅。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
对于定制要求不高且想快速使用画布引擎能力的场景,我们提供了官方画布引擎组件供开发人员嵌入到项目代码中。并通过修改协议内容有限度地控制画布引擎的表现,例如工具栏的工具透出和排布。下图展示了一个通过仅仅配置画笔和橡皮工具实现的简单画图画布引擎。
对于画布引擎有较高定制诉求的业务,我们提供了画布组件以及一系列封装了各项画布引擎能力的API,让开发人员可以更专注于GUI层的实现(图例参见上文)。
另外,画布组件也可以独立使用在一些不需要AIGC或画布引擎能力的简单场景中。下图展示了一个在画布上框选商品主体的数据标注页面。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
首先,在功能丰富度方面,画布引擎仍有进一步提升的空间。随着AIGC技术的飞速发展,我们将持续引入新的功能,以更好地支持业务需求。这些新功能将涵盖但不限于风格转换、局部修复以及场景合成等领域。
其次,目前官方画布引擎在生成模特图和商品图方面表现出色,但在处理其他题材图片时可能稍显不足。为此,我们计划在未来版本中加入自定义后端接口的支持,使开发者能够接入自己训练的模型服务,从而拓展画布引擎的应用范围和灵活性。这一改进不仅能够满足更多用户的具体需求,还将显著增强画布引擎的整体性能与适用性。
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
{
"theme": "dark",
"backend": "bizB",
"content": {
"canvas": {
"maxSize": 512,
"width": 512,
"height": 512,
"scale": 1.2,
"backgroundImage": {
"src": "backgroundImageUrl"
},
"objList": []
},
"toolBox": {
"list": [
{
"type": "fileEntry",
"title": "文件",
"children": [
{
"type": "file",
"title": "文件"
},
{
"type": "template",
"title": "模板"
}
]
},
{
"type": "adjust",
"title": "调整",
"children": [
{
"type": "cutImage"
},
{
"type": "expandImage"
},
{
"type": "clarity"
},
{
"type": "localChangeColor"
}
]
},
{
"type": "brush",
"title": "画笔",
"children": [
{
"type": "magicEraser"
}
]
},
{
"type": "filter",
"title": "滤镜"
},
{
"type": "text",
"title": "文字"
},
{
"type": "frame",
"title": "边框"
},
{
"type": "bgAdjust",
"title": "背景",
"children": [
{
"type": "background"
}
]
},
{
"type": "material",
"title": "素材"
},
{
"type": "waterMark",
"title": "水印",
"children": [
{
"type": "patternLocalPrint",
"logoUrl": "logoUrl"
},
{
"type": "patternFullPrint",
"patternImageUrl": "patternImageUrl"
}
]
}
]
}
}
}
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
团队介绍
我们是天猫技术新品营销团队,致力通过大数据、人工智能打造领先的数字化新品营销平台。
- 依托先进的大数据能力,深度解读消费者行为趋势和市场动态追踪,为品牌提供准确的新品研发方向
- 围绕AIGC算法模型的训练和应用,持续完善AI相关基础能力建设,提升算法模型的训练和应用效率
- 基于消费者端互动玩法、 新品导购场景,结合平台新品运营产品建设,全面提升商家数字化上新营销能力