UI2CODE: 自动将 UI 框架转换为 Flutter 代码
Posted UbiMaker创客工坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UI2CODE: 自动将 UI 框架转换为 Flutter 代码相关的知识,希望对你有一定的参考价值。
原文链接:
https://medium.com/p/7e0a575c193
阿里巴巴闲鱼技术团队正使用
AI
设计一种工具,这种工具可以将 UI 设计 100% 准确地转换为 Flutter 代码。正如最近我们在关于人工智能算法开发的文章中探讨的那样,自动化技术正在迅速地从需要开发者才能工作
转变为可以替代开发者的一些工作
。虽然这种转变的程度在未来几年仍有待观察,但当今的一个热点就是AI
如何解决应用程序开发中的重复和乏味的工作,使开发者把工作重点放在其他地方。
现在,阿里巴巴闲鱼二手交易平台的开发者推出了 UI2CODE
项目,将深度学习技术应用于把界面图转换为代码。凭借清晰的组件、位置和布局这些适合机器学习的特征,UI 视觉
研究为探索自动化代码生成领域提供了很好的前景。
在介绍闲鱼正在进行的工作时,我们将探讨 UI2CODE
如何分析每一个 GUI 元素
和整体的 UI 布局结构
,来生成整个应用程序的 Flutter
代码。
项目基本介绍
UI2CODE
的早期工作始于 2018 年 3 月
,当时闲鱼技术团队对其技术可行性进行了初步探索。之后用商业标准衡量该项目生成的程序,并依据此不断改进,项目至今已经经历了三轮重构。
UI2CODE
的核心原则是划分和控制 UI ,避免把鸡蛋都放在同一个篮子里的情况。为此,解决方案针对三个核心需求。首先,对于视觉上还原的精确度,要求输出的结果与原图的偏差不超一个像素;其次,虽然机器学习的结果是概率事件,但该解决方案要求结果一定要达到 100%
的准确度;最后,解决方案必须易于维护。当然对于开发者来说,生成可理解和可修改的代码只是一个起点,要确保能够在界面上进行流畅的操作,还需要生成一个合理的布局结构。
项目运行结果
经过几轮重构,闲鱼团队确定 UI2CODE
的关键功能是解决单个 card
的自动生成,并且这个功能也可以适用一个页面的自动生成。以下视频显示了 UI2CODE
插件的运行结果:(视频原链接:https://youtu.be/4r14enX-uhU)
接下来的部分我们将解释 UI2CODE
能够生成这些代码的原理。
架构设计和处理流程细分
下图展示了 UI2CODE
的架构设计
有了它,系统的过程就可以通过以下步骤简要总结:
该过程包括四个步骤:
使用深度学习技术从视觉草图中提取
GUI 元素
;使用深度学习技术来识别
GUI 元素
对应的类型;使用递归神经网络生成
DSL
(一种简洁的语言规则,交由程序和代码自动分析和处理后,可以生成真正的界面开发代码);使用语法树模板匹配
DSL
并生成相应的Flutter
代码。
以下详细讨论了 UI2CODE
系统中的关键步骤。
背景 / 前景分析
UI2CODE
进行 背景 / 前景分析的唯一目的就是把 UI图像
切割为多个 GUI 元素
,切割的结果直接确定 UI2CODE
最终生成代码的准确性。
下面白背景的 UI图像
提供了一个简单的示例:
将此 UI图像
读入内存后,将其二值化处理,代码如下所示:
1def image_to_matrix(filename):
2 im = Image.open(filename)
3 width, height = im.size
4 im = im.convert("L")
5 matrix = np.asarray(im)
6 return matrix, width, height
函数会返回一个二维矩阵,它将此 UI图像
中白色像素点的值都转换为了零:
分离图像中所有 GUI 元素
只需要五次切割。有很多种方法都可以将它们分开; 下面显示了一个横向切割的代码片段,这个递归的切割过程比实际的切割逻辑稍微简略一点:
1def cut_by_col(cut_num, _im_mask):
2 zero_start = None
3 zero_end = None
4 end_range = len(_im_mask)
5 for x in range(0, end_range):
6 im = _im_mask[x]
7 if len(np.where(im==0)[0]) == len(im):
8 if zero_start == None:
9 zero_start = x
10 elif zero_start != None and zero_end == None:
11 zero_end = x
12 if zero_start != None and zero_end != None:
13 start = zero_start
14 if start > 0:
15 cut_num.append(start)
16 zero_start = None
17 zero_end = None
18 if x == end_range-1 and zero_start != None and zero_end == None and zero_start > 0:
19 zero_end = x
20 start = zero_start
21 if start > 0:
22 cut_num.append(start)
23 zero_start = None
24 zero_end = None
这个客户端的 UI 界面
是垂直流布局,可以对其进行先横切,然后垂直切割:
此时,记录切割点 X
和 Y
的坐标,并形成切割后各部分的位置关系。在切割后会产生两组数据:六个 GUI 元素
的图片及其对应的坐标记录。在随后的步骤中,讲使用分类神经网络执行组件识别。
在实际生产过程中,背景/前景分析更加复杂,特别是在处理复杂背景时。
组件识别
在识别组件之前,必须先收集各类组件示例,然后使用TensorFlow
中提供的 CNN
和 SSD
进行训练。
UI2CODE
根据对各种类型的 GUI 元素
进行分类,包括图像,文本,形状/按钮,图标,价格等元素,然后将他们分为 UI 组件
,CI 组件
和 BI 组件
。UI 组件
主要是 Flutter
内置组件; CI 组件
主要是闲鱼的定制组件:UIkits
;BI 组件
主要是具有特定业务相关性的组件。
通常采用卷积神经网络需要根据全局特征来不断调整参数,提高组件识别的准确率。以下面的屏幕截图为例,深红色文本的两个字符(翻译为“Brand new”)是包含了图像的富文本。同时,相同的形状样式也可能存在于按钮或图标中,所以卷积神经网络需要对全局特征进行扫描来提高识别率。
组件属性提取
在各种各样的技术要点中,UI2CODE
属性提取包括组件的三个方面:形状和轮廓,字体属性和尺寸。
完成了所有 GUI 元素
信息的提取后。GUI DSL
的生成结果如下:
这些数据使程序之后能够进行布局分析。在这里,提取文本属性是最复杂。
布局分析
在 UI2CODE
的早期阶段,闲鱼团队使用四层 LSTM
网络进行训练和预测,然后由于样本量较小而转向直接硬编码。并且硬编码还具有相对简单的优点,因为之前的切割中,切割的顺序是固定的先行再列。硬编码的缺点是布局相对死板,需要与 RNN
结合来得到更好的反馈结果。
以下视频显示了通过四层 LSTM
机制预测布局结构的结果; 在这里,整体的 UI
布局结构类似于建筑物的框架,而每一个 UI
层代码则类似使用 GUI
的属性进行的室内设计。(视频原链接:https://youtu.be/3c62yaTZU1I)
代码生成插件
AI
基本上都是概率问题,而自动生成的代码却需要非常高的可恢复性和 100%
的准确性。但由于概率的浮动使得 AI
难以达到这种精确度,因此需要一个可编辑的工具来使开发人员能够快速理解和修改 UI
布局结构。
为此,闲鱼团队为 UI2CODE
生成的 DSL TREE
实现了基于模板的匹配方法,其中代码模板的内容由经验丰富的 Flutter
技术人员定义。到目前为止,这已被证明是代码实现的最佳方法。
代码模板中加入了一些标记,Intellij
插件用于检索和替换 Flutter
项目中的相应 UIkit
,以便提高代码重用率。
整个插件项目需要提供自定义 UIkit
功能,包括 DSL
树的检索,替换,验证,创建,修改和图形识别。总之,这与 ERP
类似,所以跟ERP
一样,该项目需要时间进行改进。
关键要点
在本文介绍的五个关键步骤中,有四个涉及计算机视觉的问题通过 AI
连接在一起。这对将代码发布到在线环境中这件事提出了非常严格的要求,并且 AI
具有概率性使这个项目具有重大挑战。为了继续解决这些问题,闲鱼技术团队选择专注于机器视觉功能,同时使用 AI
技术作为构建 UI2CODE
系统的补充,并继续专注于 AI
技术,使 UI2CODE
成为一种优秀的自动化代码生成工具。
校对:周震杭
以上是关于UI2CODE: 自动将 UI 框架转换为 Flutter 代码的主要内容,如果未能解决你的问题,请参考以下文章