UI2Code智能生成Flutter代码–整体设计篇

46次阅读

共计 2952 个字符,预计需要花费 8 分钟才能阅读完成。

摘要:UI2CODE 项目是闲鱼技术团队研发的一款通过机器视觉理解 +AI 人工智能将 UI 视觉图片转化为端侧代码的工具。
背景:
随着移动互联网时代的到来,人类的科学技术突飞猛进。然而软件工程师们依旧需要花费大量精力在重复的还原 UI 视觉稿的工作。UI 视觉研发拥有明显的特征:组件,位置和布局,符合机器学习处理范畴。能否通过机器视觉和深度学习等手段自动生成 UI 界面代码,来解放重复劳动力,成为我们关注的方向。
UI2CODE 简单介绍:
UI2CODE 项目是闲鱼技术团队研发的一款通过机器视觉理解 +AI 人工智能将 UI 视觉图片转化为端侧代码的工具。
2018 年 3 月 UI2CODE 开始启动技术可行性预研工作,到目前为止,经历了 3 次整体方案的重构(或者重写)。我们参考了大量的利用机器学习生成代码的方案,但都无法达到商用指标,UI2CODE 的主要思想是将 UI 研发特征分而治之,避免鸡蛋放在一个篮子里。我们着重关注以下 3 个问题的解法:
视觉稿还原精度:我们的设计师甚至无法容忍 1 像素的位置偏差;
准确率:机器学习还处于概率学范畴,但我们需要 100% 的准确率;
易维护性:工程师们看的懂,改的动是起点,合理的布局结构才能保障界面流畅运行。
UI2CODE 运行效果:
UI2CODE 插件化运行效果,如下视频:进过几轮重构,最终我们定义 UI2CODE 主要解决 feeds 流的卡片自动生成,当然它也可以对页面级自动生成。
视频地址:https://yunqivedio.alicdn.com…
架构设计:

简化分析下 UI2CODE 的流程:

大体分为 4 个步骤:
1. 通过机器视觉技术,从视觉稿提取 GUI 元素
2. 通过深度学习技术,识别 GUI 元素类型
3. 通过递归神经网络技术,生成 DSL
4. 通过语法树模板匹配,生成 flutter 代码
版面分析
版面分析只做一件事:切图。
图片切割效果直接决定 UI2CODE 输出结果的准确率。我们拿白色背景的简单 UI 来举例:

上图是一个白色背景的 UI,我们将图片读入内存,进行二值化处理:
def image_to_matrix(filename):
im = Image.open(filename)
width, height = im.size
im = im.convert(“L”)
matrix = np.asarray(im)
return matrix, width, height
得到一个二维矩阵:将白色背景的值转化为 0.
像切西瓜一样,我们只需要 5 刀,就可以将 GUI 元素分离,切隔方法多种多样:(下面是横切的代码片段,实际切割逻辑稍微复杂些,基本是递归过程)
def cut_by_col(cut_num, _im_mask):
zero_start = None
zero_end = None
end_range = len(_im_mask)
for x in range(0, end_range):
im = _im_mask[x]
if len(np.where(im==0)[0]) == len(im):
if zero_start == None:
zero_start = x
elif zero_start != None and zero_end == None:
zero_end = x
if zero_start != None and zero_end != None:
start = zero_start
if start > 0:
cut_num.append(start)
zero_start = None
zero_end = None
if x == end_range-1 and zero_start != None and zero_end == None and zero_start > 0:
zero_end = x
start = zero_start
if start > 0:
cut_num.append(start)
zero_start = None
zero_end = None

客户端的 UI 基本都是纵向流式布局,我们可以先横切在纵切。
将切割点的 x,y 轴坐标记录下来,它将是处理组件位置关系的核心。切割完成后,我们获取到 2 组数据:6 个 GUI 元素图片和对应的坐标系记录。后续步骤通过分类神经网络进行组件识别。
在实际生产过程中,版面分析会复杂些,主要是在处理复杂背景方面。
关注我们的技术公众号,我们后续会详细分解。
组件识别:
进行组件识别前我们需要收集一些组件样本进行训练,使用 Tensorflow 提供的 CNN 模型和 SSD 模型等进行增量训练。
UI2CODE 对 GUI 进行了几十种类型分类:IMAGE,TEXT,SHAP/BUTTON,ICON,PRICE 等等,分别归类为 UI 组件,CI 组件和 BI 组件。
UI 组件,主要针对 flutter 原生的组件进行分类。
CI 组件,主要针对闲鱼自定义 UIKIT 进行分类。
BI 组件,主要针对具备一定业务意义的 feed 卡片进行分类。

组件的识别需要反复的通过全局特征反馈来纠正,通常会采用 SSD+CNN 协同工作,比如下图的红色“全新“shape,这该图例中是 richtext 的部分,同样的 shape 样式可能属于 button 或者 icon。

属性提取:
这块的技术点比较杂,归纳起来需要处理 3 部分内容:shape 轮廓,字体属性和组件的宽高。

完成属性提取,基本上我们完成所有 GUI 信息的提取。生成的 GUI DSL 如下图:

通过这些数据我们就可以进行布局分析了。其中文字属性的提取最为复杂,后续我们会专门介绍。
布局分析:
前期我们采用 4 层 LSTM 网络进行训练学习,由于样本量比较小,我们改为规则实现。规则实现也比较简单,我们在第一步切图时 5 刀切割的顺序就是 row 和 col。缺点是布局比较死板,需要结合 RNN 进行前置反馈。
视频地址:https://yunqivedio.alicdn.com…
视频中展示的是通过 4 层 LSTM 预测布局结构的效果,UI 的布局结构就像房屋的框架,建造完成后通过 GUI 的属性进行精装修就完成了一个 UI 图层的代码还原工作。
代码生成及插件化:
机器学习本质上来说还属于概率学范畴,自动生成的代码需要非常高的还原度和 100% 的准确率,概率注定 UI2CODE 很难达到 100% 的准确率,所以我们需要提供一个可编辑工具,由开发者通过工具能够快速理解 UI 的布局结构和修改布局结构。
我们将 UI2CODE 生成的 DSL TREE 进行代码模板化匹配,代码模板的内容由资深的 flutter 技术专家来定义,它代表目前我们发现的最优代码实现方案。

代码模板中会引入一些标签,由 Intellij plugin 来检索 flutter 工程中是否存在对应的自定义 UIKIT,并进行替换,提高代码的复用度。

整个插件化工程需要提供自定义 UIKIT 的检索,替换和校验工作,以及 DSL Tree 的创建,修改,图示等工作,总体来说,更像 ERP 系统,花费一些时间能够做的更加完美。

小结:
本篇我们简单介绍了 UI2CODE 的设计思路,我们将整个工程结构分为 5 个部分,其中 4 块内容核心处理机器视觉的问题,通过机器学习将它们链接起来。代码的线上发布是非常严格的事情,而单纯的机器学习方式,很难达到我们要求,所以我们选择以机器视觉理解为主,机器学习为辅的方式,构建整个 UI2CODE 工程体系。我们将持续关注 AI 技术,来打造一个完美的 UI2CODE 工具。

本文作者:闲鱼技术 - 上叶阅读原文
本文为云栖社区原创内容,未经允许不得转载。

正文完
 0