在做音樂webapp的時候,被騰訊的一款本地音樂播放器(輕聽)的播放介面驚豔到了(如下圖),於是決定‘複製’下來。
![](https://i.iter01.com/images/903fbaed29faaa7959049efe68a0003ff8152983f26b944eb0919f5d97d9990c.png)
擼起袖子就開始幹~
首先想到的是繪入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值
![](https://i.iter01.com/images/0b4ed237c92c18f5668e80ee2653d6b76268fdafdb886f62eafe87c1b61cd578.png)
需要使用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';
}複製程式碼
在專案中我就是用這個外掛,成果是這樣的
![播放介面](https://i.iter01.com/images/b1754d0cc83dcc677b10ef20e58b6680b3f8a389dafa214ddf232f75546824dc.gif)
對專案感興趣的點這裡?專案地址
最後再給大家附上另外兩款顏色提取外掛
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);複製程式碼
結果
![](https://i.iter01.com/images/111870cc678464ff95ba6407086b28444e6144d199247e06adfd952e734c7b2c.png)
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())複製程式碼
![](https://i.iter01.com/images/208852ea960edea427d5852dee796cbf999c3bc5d3b70512bc4f16462b74addd.png)
以上三個樣例都是提取的同一張圖片所得結果,看一下橫向對比
![](https://i.iter01.com/images/b83d98544ad091043e123c8a82e228dbe75156c99579d51355d9761eafac4c7c.png)
初步測試還是rgbaster提取出來的顏色最接近了,不過在專案中測試有些情況偏差有點遠。而vibrant.js主要還是著重於把圖片的顏色提取出來分類,如樣例所示,結果分為暗色、亮色、突出色之類,提取主題色還是rgbaster好使。
注意: 這三款外掛均是利用把圖片繪入canvas獲取圖片資料,如果不是同源圖片將無法使用
以上便是這次的文章分享了,歡迎留言相互學習~