在做音樂webapp的時候,被騰訊的一款本地音樂播放器(輕聽)的播放介面驚豔到了(如下圖),於是決定‘複製’下來。

擼起袖子就開始幹~
首先想到的是繪入canvas中利用getImageData提取資料然後分析得到主題色,因為用的qq音樂api遇到了跨域問題,在解決跨域問題後(具體方法看這裡跨域那些事),緊接著的問題是如何提取主題色。
關於顏色提取的大概演算法有這些
- 魔法數字法
- 八叉樹提取法
- 最小插值法
- 中位切分法
- 聚類
- ......
具體的就看看這兩篇啦
圖片主題色提取演算法小結
影象主題色提取演算法
接下來介紹幾款顏色提取的js外掛
1.rgbaster.js
github地址。這是一段小指令碼,可以提取圖片的主色、次色。
使用
首先肯定是引入啦,然後上程式碼
const img = document.querySelector('img');
// 或者
// const img = 'http://example.com/image.jpg';
RGBaster.colors(img, {
// 調色盤大小,就是提取的樣本,越大越精確,同時效能越差
paletteSize: 30,
// 顏色排除
exclude: [ 'rgb(255,255,255)', 'rgb(0,0,0)' ],
success: function(payload) {
console.log('Dominant color:',payload.dominant);// 提取出來的主色
console.log('Secondary color:', payload.secondary);// 次色
console.log('Palette:', payload.palette); // 調色盤
}})複製程式碼
提取出來的結果是一個rgb值

需要使用rgba值的同學,只需要正則一下,提取出來再拼接就好啦
const c = payload.dominant.match(/\d+/g);
const Color = `rgba(${c[0]},${c[1]},${c[2]},0.8)`;複製程式碼
顏色有深有淺,暗色的話,黑色字型就看不清了,文字顏色得隨著背景色取反,我們可以把rgb值轉化成灰度值來判斷顏色深淺
let fontColor;
const grayLevel = c[0] * 0.299 + c[1] * 0.587 + c[2] * 0.114;
if (grayLevel >= 192) {
// 若為淺色,把文字設定為黑色
fontColor = '#000';
} else {
fontColor = '#fff';
}複製程式碼
在專案中我就是用這個外掛,成果是這樣的

對專案感興趣的點這裡?專案地址
最後再給大家附上另外兩款顏色提取外掛
2.Color Thief
使用
// 提取主色
const img = document.querySelector('img');
var colorThief = new ColorThief();
console.log(colorThief.getColor(img));
}
// 調色盤
var colorThief = new ColorThief();
colorThief.getPalette(sourceImage, 8);複製程式碼
結果

3.vibrant.js
從影象中提取突出的顏色。
Vibrant.js是Android支援庫中令人敬畏的Palette類的JavaScript埠。
專案地址
使用
const img = document.querySelector('img');
var vibrant = new Vibrant(img);
var swatches = vibrant.swatches()
for (var swatch in swatches)
if (swatches.hasOwnProperty(swatch) && swatches[swatch])
console.log(swatch, swatches[swatch].getHex())複製程式碼

以上三個樣例都是提取的同一張圖片所得結果,看一下橫向對比

初步測試還是rgbaster提取出來的顏色最接近了,不過在專案中測試有些情況偏差有點遠。而vibrant.js主要還是著重於把圖片的顏色提取出來分類,如樣例所示,結果分為暗色、亮色、突出色之類,提取主題色還是rgbaster好使。
注意: 這三款外掛均是利用把圖片繪入canvas獲取圖片資料,如果不是同源圖片將無法使用
以上便是這次的文章分享了,歡迎留言相互學習~