使用ColorfulImg獲取圖片主題色!

BrownHu發表於2018-09-11

取色網站

使用ColorfulImg獲取圖片主題色!
前幾天遇到了獲取圖片主題色的需求,於是去找了一些相關的部落格,發現實現起來相當簡單,於是自己開發了一個獲取圖片主題色的網站---ColorfulImg 大家可以通過上傳/拖拽圖片的方式獲取圖片主題色。

歡迎Star~

ColorfulImg

Colorfulimg是一個能夠通過canvas獲取圖片主題色的js工具庫。

安裝:

npm i colorfulimg

使用方法:

let colorfulimg = require('colorfulimg') 
let myImg = document.getElementById('myImg')
let rgb = colorfulImg(myImg);
複製程式碼

這是專案地址

歡迎star~

ColorfulImg實現思路

下面說一下實現思路,主要是通過canvasgetImageData()方法獲取圖片每個畫素點的rgba資料。通過取得平均值的方法來算出圖片主題色。 所以要想實現此效果有兩個限制:

  • 網站和圖片必須是相同的域名(getImageData()限制圖片必須同源)
  • 瀏覽器必須支援canvas

在canvas中繪製img影像

  1. 首先我們要新建一個canvas標籤並且訪問它的繪畫上下文:
let canvas = document.createElement('canvas')
let context = canvas.getContext && canvas.getContext('2d')
複製程式碼
  1. 繪製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
複製程式碼

在我第一次測試的時候遇到了跨域的問題:

使用ColorfulImg獲取圖片主題色!

圖片如果不同源的話必須要加crossorigin="anonymous"的屬性,並且伺服器儲存那邊也要開放相應的許可權才行。 <img id="img" crossorigin="anonymous">

處理獲取的顏色資料

我們先log一下拿到的資料是什麼吧:

使用ColorfulImg獲取圖片主題色!

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

使用ColorfulImg獲取圖片主題色!

也就是說按順序來看前四位組成一個以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;
}
複製程式碼

相關文章