使用ColorfulImg獲取圖片主題色!

大家可以通過上傳/拖拽圖片的方式獲取圖片主題色。
歡迎Star~
ColorfulImg
Colorfulimg是一個能夠通過canvas獲取圖片主題色的js工具庫。
安裝:
npm i colorfulimg
使用方法:
let colorfulimg = require('colorfulimg') let myImg = document.getElementById('myImg') let rgb = colorfulImg(myImg); 複製程式碼
歡迎star~
ColorfulImg實現思路
下面說一下實現思路,主要是通過canvas的getImageData()方法獲取圖片每個畫素點的rgba資料。通過取得平均值的方法來算出圖片主題色。 所以要想實現此效果有兩個限制:
- 網站和圖片必須是相同的域名(getImageData()限制圖片必須同源)
- 瀏覽器必須支援canvas
在canvas中繪製img影象
- 首先我們要新建一個canvas標籤並且訪問它的繪畫上下文:
let canvas = document.createElement('canvas') let context = canvas.getContext && canvas.getContext('2d') 複製程式碼
- 繪製img影象,X軸與Y軸的起始點都設定為0:
let myImg = document.getElementById('myImg') context.drawImage(myImg , 0, 0) 複製程式碼
獲取圖片顏色資料getImageData()
getImageData()這個API需要四個引數,前兩個是獲取圖片資料的起點,後兩個是提取的影象資料矩形區域的寬度和高度,我們要得到圖片全部的資料所以後兩個引數就是圖片的寬高,於此同時我們也要把canvas的寬高設定為圖片的寬高能完全裝下圖片。
let height = canvas.height = imgEl.height let width = canvas.width = imgEl.width let data = context.getImageData(0, 0, width, height).data 複製程式碼
在我第一次測試的時候遇到了跨域的問題:

圖片如果不同源的話必須要加 crossorigin="anonymous"
的屬性,並且伺服器儲存那邊也要開放相應的許可權才行。 <img id="img" crossorigin="anonymous">
處理獲取的顏色資料
我們先log一下拿到的資料是什麼吧:

是一個有著一堆資料的陣列,這些資料是什麼呢?我們先看一下MDN:

也就是說按順序來看前四位組成一個以RGBA順序的資料: rgba(red, green, blue, alpha)
對於獲取的圖片資料透明度(alpha)都是255也就是不透明的所以我們不對透明度做處理,之後我們只需要把rgb的其他三個值分別求和再取均值就可以得到圖片的主題色了!
let count = 0 let i = 0 let blockSize = 1 while ( (i += blockSize * 4) < length ) { ++count rgb.r = data[i] + rgb.r rgb.g = data[i+1] + rgb.g rgb.b = data[i+2] + rgb.b } rgb.r = ~~(rgb.r/count) rgb.g = ~~(rgb.g/count) rgb.b = ~~(rgb.b/count) 複製程式碼
最終程式碼
function colorfulImg(img){ let canvas = document.createElement('canvas'), context = canvas.getContext && canvas.getContext('2d'), height,width,length,data, i = -4, blockSize = 5, count = 0, rgb = {r:0,g:0,b:0} height = canvas.height = imgEl.height width = canvas.width = imgEl.width context.drawImage(imgEl, 0, 0); data = context.getImageData(0, 0, width, height).data length = data.length while ( (i += blockSize * 4) < length ) { ++count; rgb.r += data[i]; rgb.g += data[i+1]; rgb.b += data[i+2]; } rgb.r = ~~(rgb.r/count); rgb.g = ~~(rgb.g/count); rgb.b = ~~(rgb.b/count); return rgb; } 複製程式碼