使用ColorfulImg獲取圖片主題色!

取色網站

前幾天遇到了獲取圖片主題色的需求,因而去找了一些相關的博客,發現實現起來至關簡單,因而本身開發了一個獲取圖片主題色的網站--- ColorfulImg 你們能夠經過上傳/拖拽圖片的方式獲取圖片主題色。

歡迎Star~git

ColorfulImg

Colorfulimg是一個可以經過canvas獲取圖片主題色的js工具庫。github

安裝:npm

npm i colorfulimgcanvas

使用方法:跨域

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

這是項目地址數組

歡迎star~瀏覽器

ColorfulImg實現思路

下面說一下實現思路,主要是經過canvasgetImageData()方法獲取圖片每一個像素點的rgba數據。經過取得平均值的方法來算出圖片主題色。 因此要想實現此效果有兩個限制:bash

  • 網站和圖片必須是相同的域名(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
複製代碼

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

圖片若是不一樣源的話必需要加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;
}
複製代碼
相關文章
相關標籤/搜索