作者:閑魚技術-青頁
一直以來, 如何從‘視覺稿’精确的還原出 對應的UI側代碼 一直是端側開發同學工作裡消耗比較大的部分,一方面這部分的工作 比較确定缺少技術深度,另一方面視覺設計師也需要投入大量的走查時間,有大量無謂的溝通和消耗。
閑魚團隊 在去年做了一個很特别的黑科技 基于圖檔直接翻譯成對應的UI側代碼,具體完成的部分,我們有一個示範的視訊
很多人會比較好奇,為什麼我會堅持使用圖檔做為輸入源,一方面基于 sketch 或者 photoshop 等插件 相對容易拿到确定性的資訊,圖檔在某些方面容易丢失一些特征;另外基于圖檔的分析其實挑戰更大。我們做 這個選擇 有以下原因,首先圖檔作為最終的産出物,更直覺和确定性,另外這個鍊路裡對上遊不會有限制性。最後也是最重要的一點 基于圖檔的應用場景會更普适,類似場景 例如自動化測試能力的支援,基于竟品直接截圖來套用我們自己的資料源找體感,等場景是其他的方案做不到的。
上面我們在講項目本身的意義和選型上的一些判斷,後面我們會簡單介紹下項目的基本流程
首先我們會使用深度學習的方式,來找到對應的 UI單元,包括基礎的UI元件,例如 imgview textview 等,接下來是自定義的BI元件例如 price 等, 最後我們會尋找已經被實作過的業務元件。下面是一個 常見的業務場景,我們框選了每個對應的部分,示範上面的業務邏輯

接下來我們會基于已經檢測出的元素,來做對應的元素提取,這個部分我們會去分析系統渲染的原理 并使用 opencv 的方法來做對應的功能
項目整體的流程,我們用下面的這個圖來表示
在整個項目落地的過程中,我們遇到很多的技術困難的點,下面我會講2個有意思的點
第一個我們會發現 autoui 的整個流程結構是一個非常典型的上下遊的流形式,每個關鍵的單元都會依賴上遊的輸出,并且為下遊提供标準的輸入,我們在項目的開始時候,因為沒有特别好的去定義切分的關系,經常會出現當一個同學調整和PUSH代碼後,會對整個鍊路造成很大的影響,是以我們對架構設計做了一個關鍵的更新我們定義叫流式的架構,我們用一個圖讓大家更好的來了解這一塊
在這個單元裡 我們定義了 unti,tasks,server三個單元,unit本身是最小粒度的功能切分,tasks是unit的組合,server 會提供具體的服務,每個部分都會為上下遊 提供輸入和輸出,架構切分的好處是,所有的子產品都有标準的輸入和輸出的部分,我們可以通過對子產品的MOCK來解決标準化調試的問題,另外當一些基礎的功能完成後,我們可以通過搭積木的方式來組合自己想要的 tasks 和 server ,在我們做了架構調整後,因為整體的切分更合理,也減少了上下遊的依賴,對項目的快速疊代産生了很大的幫助。
後續 在架構側我們還做了一個有意思的點,因為 我們的服務有些是需要跑在服務端,有些是需要跑在用戶端上,是以我們設計了一個可以在用戶端和服務端同構的場景,目的是希望開發的人員隻需要關系界面和服務的通信,但并不需要關注具體服務的部署關系
上面我們講了一個架構的設計,後面我們希望講一個具體的布局問題具體解法,把靜态的DSL轉成一個合适的布局屬性的TREE,在這個部分我們還是分析了能産生布局的因素,如下圖所示
這樣一個非常常見的布局,我們拆分出了影響布局的部分,通過元素位置、間距、容器位置分析,我們參考了 flex 布局的标準,也參考了 新的 grid 的布局标準,通過枚舉元素在位置中站位的比例,來得出對應的關系。
但是我們最後還是遇到一些Bad Case,如何寫出更貼近人寫出的UI側代碼,我們還是需要去參考類似語意的部分,相似度的部分 我們才能得到真正合理的布局,例如上面的 這個例子,如果按照枚舉的布局去推斷的話,我們很容易得到 一個四個橫列的布局關系,但是通過語意和相似度的部分,我們會很容易的推斷出一個 gridview 的布局關系。
去年整體 我們已經比較好的 讓整個工程在業務側 開始跑起來 開始讓大家能解放出來 做一些更需要思考的事情,并把我們的項目 展示給了 google團隊,也得到了很多的關注。
未來,我們還是希望通過更好的分析能力(包括 容器識别、複雜的背景識别、精确的語意了解能力),産生出更接近開發人員手寫的代碼,進而完全取代 ‘切圖’ 這個工作,另外我們也在看在這個階段我們已經能夠 讓機器來解放開發鍊路的最前面一段,後面 在一些弱互動、強展示的部分,例如導購或者營銷這樣的場景,我們其實通過資料模型的抽象和識别、甚至固定的PRD的識别 有可能我們是能真正的解放整段的人力投入,讓大家從偏确定性的需求實作中解放出來。另外 我們也開始和 D2C 這樣的項目 一起共建,希望在閑魚裡已經實作的部分,能夠解決更多人的問題,解放更多的生産力。