相信很多人應該都知道8月份發生的就希望APP主題顏色隨手機殼自動調整的流血事件,當晚刷爆朋友圈。然而第二天我接到一個需求,設計希望前端自動讀取banner的主題色在圖片上面添加主題色的漸變蒙版,當時我默默的拿出手機播放了前一天晚上刷爆朋友圈視頻,然后再把描述也給UI讀了一遍,是否他就懂了我的意思,轉身就改設計稿去了,這件事也就偶爾被當做笑料談一談。但當時的我竟沒有仔細想一想,沒有研究就果斷的拒絕UI,現在回想起原來被當做笑料的是我自己。。。
需求描述
要求就是達到如下效果,獲取每一個節目單 banner 的主題色彩,然后在banner上加上一層漸變的主題色,因為 banner 為電台客戶自己上傳,不可控,所以需要開發添加。
實現方案
1、獲取點色
簡單邏輯獲取主色調當然就是直接判斷哪個色彩的RGB值出現次數最多就取哪個顏色了,如果要深入考慮的話當然還有密集度重要因素,這里就不做贅述了,我們就采用簡單粗暴的方案就可解決當前需求。
我們可以通過 canvers 的 getImageData 方法獲取到每一個像素點的 ImageData 對象,ImageData.data 中存儲着我們需要的具體數據,方法如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <canvas id="canvas" width="300" height="300"></canvas> 9 </body> 10 11 <script type="text/javascript"> 12 let img = new Image() 13 let canvas = document.getElementById('canvas') 14 let ctx = canvas.getContext('2d') 15 16 img.onload = function() { 17 ctx.drawImage(img, 0, 0) 18 img.style.display = 'none' 19 let imgData = (ctx.getImageData(0, 0, img.width, img.height)).data 20 } 21 22 img.src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=182623993,1093186456&fm=27&gp=0.jpg" 23 img.crossOrigin="anonymous" 24 </script> 25 </html>
如果你對 canvers 的 getImageData 方法不勝了解,請點擊這里
問題:
Ⅰ、這里因為 canvers 有安全監測機制,所以 img 的地址不能使用本地的圖片,會涉及跨域的問題,當然如果你比較皮,非要使用本地圖片作為測試數據,那也不是沒辦法,這里提供兩個方案:
① 寫成本地圖片后頁面使用 Firefox 打開,不會報錯
② 借助第三方中轉,隨便找個網址注冊,上傳測試圖片作為頭像后將頭像地址拿過來,就OK
Ⅱ、canvers img 如果使用網絡地址還會觸發另一個問題,就是地址得以 https 協議傳輸,否則同樣報錯。如果你對 http、https 不勝了解,請單擊這里
2、數據處理
我們拿到點色數據后接下來的工作當然就是對二維色點數組的 RGB 值做處理,這里就需要一定的算法來支撐。
要注意的是顏色是有三個值來控制的(RGB),如果取單值來統計的話就顯得粗漏,所以就需要分別對R、G、B的值進行統計。
主要的一些算法有 顏色量化法 → 八叉樹算法、中位切分法,聚類 → KMeans 算法,色彩建模 等方法,如果你想了解一下,請點擊這里
這里我們選取八叉樹算法來處理數據,八叉樹顧名思義共八層,每層每個節點都有八個子節點(葉子節點除外)