UI2CODE智能生成代码——组件识别篇
背景
在《UI2CODE---- 整体设计篇》中,我们介绍了UI2CODE工程的整体流程:
在组件识别这个环节,需要有一种处理布局信息的方法,来解析和计算控件间的布局关系(比如识别业务组件(BI组件)和查找重复布局),以此来提高最终代码的可用性。
在这篇文章,我们将介绍一种布局信息的结构化方法: " 连线法",以及一种布局间的计算和比较方法: " 引导连线法"。
首先来看我们需要解决的问题。
问题一:识别业务组件
01 目的:代码复用
业务组件是指某些特定的卡片,比如一个商品详情卡片,这些卡片会在不同页面出现,而这些卡片的代码一般是已经存在的。我们在拿到一张图片的时候,需要先识别出这些组件,这样这一区块就能复用已有的组件代码,而不会造成很多冗余的一次性代码。
0 2 老解法:利用SDD模型做物体检测
如果把寻找业务组件这个问题看成从一张大图片上寻找小图片的话,那么最直接的做法就是用一个物体检测模型(比如SSD)来做,这样只要训练模型来识别每个业务组件的图片就可以了。因此我们尝试了用训练SSD模型来解决这个问题。
0 3 存在的问题:训练困难,结果不可控
经过训练和测试以后,我们发现用物体检测模型来解这个问题的弊端:
需要造大量样本。由于图片信息丰富,为了避免过拟合,需要造大量样本来训练。
训练困难,增加新的业务组件成本太高。每增加一个新的业务组件,就需要先造这个组件的样本,然后重新调整训练模型。
训练结果不可控。对于一些badcase,没有一些直接有效的方式来做调整和控制,只能不断调整样本。
0 4 思考:是否可以利用已有的控件信息
既然前面已经解析出了各个控件的信息(包含类型以及位置等),那么我们是否可以直接利用这些信息来做处理呢?因此我们想要寻找一种新的方式,来处理和解析控件信息,利用这些信息来实现类似"物体检测"功能。
问题二:重复布局
0 1 目的:提升代码可用性
如上图这个case,对于类似"GridView"的这种布局,我们理想的布局方式应该是有8个Item,每个Item包含一个TextView和ImageView(上图左边)。
0 2 存在的问题:无法识别重复布局
然而实际情况是,我们没有做重复布局的检测,因此布局的时候变成了4行(上图右边)。
0 3 思考:如何比较布局是否重复
为了解决上面的问题,我们就需要寻找一种方法,从多个控件信息中,找到一些规律,自动找到这些具有相似情况的布局。
问题分析
以上就是我们需要解决的两个问题,我们分析这两个问题,会发现他们有一些共同点:
都是由多个控件组成大的布局
布局间需要进行比较,寻找"相似布局"
都是非结构化数据:无法直接比较、计算
解决思路
首先我们需要将非结构化数据转换为结构化数据(或者叫特征提取),这个思路可以参考图片分类任务的做法,不管是聚类算法还是AI模型,都是先做特征提取,再进行进一步处理,实际上做的就是非结构化数据转换成结构化数据。
因此,我们的问题解决思路也就分为两步:
1. 布局信息结构化:将布局信息处理成结构化的数据
2. 布局比较:对布局进行比较、计算,寻找相似布局
布局信息结构化
为了分析控件间的关系,我们可以先从简单的开始,看一下两个控件之间的关系都包含哪些信息。
01 控件间的关系
两个控件间的关系,包含以下2个方面的信息:
1. 控件属性 (类型、文本内容、位置、大小)
2. 方向、距离、对齐方式 (用连线表达)
控件属性
对于控件属性,可以直接用它自身表示,包含控件类型、内容、位置、大小等
方向和距离
对于两个控件的方向和距离,我们可以用一条虚拟的"连线"来表示,这条连线连接两个控件的中心点。这样,这条连线的长度和角度就可以表示两个控件的方向和距离。比如上图,我们可以得到:一个TextView在一个ImageView正上方,距离xxx像素。
对齐方式
但是除了角度和方向,实际上还存在着一个 " 对齐方式"信息。
比如上图这个case,如果我们还是连接两个控件的中心点的话(图中蓝色虚线),那这左右两边的图就是指不同的布局(因为两个控件的角度和距离都不一样)。
但是由我们人"肉眼"来看,我们会认为这两个布局是一样的,都是左边一个头像,右边上面跟着一个文本。
因此,我们需要连接TextView的"左边中点"(图上红色实线),这样,不同的连接点位置,就可以表达不同的对齐方式。左对齐的TextView连接左边中点,右对齐的TextView连接右边中点,居中的连接中心点。
0 2 定义数据结构
有了上面的分析,我们就可以定义一个数据结构。我们用一个Connection对象表达2个控件间的布局关系,它包含:
控件1属性 (类型、位置大小等)
控件2属性 (类型、位置大小等)
控件1和控件2间的多条连线 (角度、距离)
这样,2个Connection之间就可以进行比较、判断是否"匹配"
0 3 Connection匹配计算
两个Connection之间是否"匹配",必须满足:
控件信息匹配(类型一致、ImageView面积相似度满足要求等)
方向和距离匹配(连线的余弦相似度)
其它自定义的匹配要求
0 4 整个布局的表示
两个控件间的关系可以用一个Connection来表示,那么多个控件组成的大布局,就可以用一组Connection来表示。
我们对每两个控件建立一个Connection,就可以得到一个Connection数组
这样,我们的第一步"布局信息结构化"就完成了。
布局间比较
将布局信息转换成Connection数组以后,我们就可以开始利用这些信息来查找相似布局。
首先,我们可以理解这样一个概念,就是:
一个布局,可以看成由一组Connection对象串联起来,得到的一个 "路径"
如上图,蓝色圈内的布局可以看成一组Connection串联起来(红色连线)。
那么, 寻找相似布局,就是寻找两条相似 "路径"的过程
0 1 引导连线法
为了寻找相似路径,我们定义了一个"引导连线法"。
所谓 "引导连线法",就是一个 Leader,一个 Follower,Follower 尝试着跟随 Leader 走出一条一样的路径。
步骤如下:
计算出所有相互匹配的Connection(如下图所有绿色的连线)
定义一个"Leader"叫A,一个 "Follower" 叫B
随机选择一条绿色连线作为A的初始路径,与其相匹配的另一条绿色连线作为B的初始路径
A尝试着继续往前走,找到下一个路径(绿色连线),B尝试着跟随
如果B能跟的上(即找到了一条路径,刚好与A想走的路径匹配上),那么A继续往下走,如果B跟不上,那么A换条路径继续尝试。
直到A走的路径B怎么也跟不上时,A和B走过的路径所对应的那些控件,就是拥有相似布局的控件。
应用效果
有了结构化的方法和"引导连线法",我们就可以应用到上述两个问题。
0 1 业务组件
应用
对业务组件进行结构化处理(图左红色连线)
对待处理图片进行结构化处理
找到他们之间可以"匹配"的Connection(图右绿色部分)
用"引导连线法"找到相似的布局
效果
应用这套算法以后,扩展要识别的组件变得非常简单,只要把新组件的的结构化数据预先计算好存储起来,在查找的时候应用"引导连线法"即可。
**0 2 ** 重复布局
应用
查找重复布局步骤如下:
- 计算自身所有控件的Connection
2. 寻找自身Connection中,互相匹配的 Connection
3. "引导连线"法寻找匹配的布局"pair"
4. 多个"pair"串联组成一个重复布局
5. 继续尝试对重复布局的每个Item做拆分,可得到"GridView"
这样,最终我们就可以找到,图上有8个布局相似的Item。
效果
应用这套算法,可以查找出页面上任意的重复布局,无论是简单的还是复杂的,极大得提升了代码的可用性。
结语
以上就是我们针对布局信息的处理和计算的整体思路。当然其中还有很多复杂细节需要处理,比如相似布局相似度计算、重复布局多个"pair"组合起来的时候组合条件的判断、重复布局其它额外信息的提取等。但是总体上都是围绕着"布局信息结构化"和"引导连线法展开",我们也在不断的继续探寻和持续优化各个环节。
作者暂无likerid, 赞赏暂由本网站代持,当作者有likerid后会全部转账给作者(我们会尽力而为)。Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.
Support author:
Author's Filecoin address:
Or you can use Likecoin to support author: