Используйте ColorfulImg, чтобы получить цвет темы изображения!

внешний интерфейс сервер JavaScript Canvas

сайт выбора цвета

Несколько дней назад я столкнулся с необходимостью получить цвет темы изображения, поэтому я зашел в некоторые связанные блоги и обнаружил, что это довольно просто реализовать, поэтому я разработал веб-сайт для получения цвета темы изображения: -ColorfulImgВы можете получить цвет темы изображения, загрузив или перетащив изображение.

Добро пожаловать в Звезду~

ColorfulImg

Colorfulimg — это библиотека инструментов js, которая может получить цвет темы изображений через холст.

Установить:

npm i colorfulimg

Инструкции:

let colorfulimg = require('colorfulimg') 
let myImg = document.getElementById('myImg')
let rgb = colorfulImg(myImg);

Это адрес проекта

Добро пожаловать звезда ~

Идеи реализации ColorfulImg

Поговорим о реализации идеи, в основном черезcanvasизgetImageData()Метод получает данные rgba каждого пикселя изображения. Цвет темы изображения рассчитывается по среднему значению. Таким образом, есть два ограничения для достижения этого эффекта:

  • Веб-сайт и изображение должны иметь одно и то же доменное имя (getImageData() ограничивает изображение одним и тем же источником)
  • Браузер должен поддерживать холст

нарисовать изображение img на холсте

  1. Сначала нам нужно создать новый тег холста и получить доступ к его контексту рисования:
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 требует четыре параметра, первые два являются отправной точкой для получения данных изображения, последние два — это ширина и высота прямоугольной области извлеченных данных изображения, мы хотим получить все данные изображения, поэтому последние два параметра являются шириной и высотой изображения. В то же время нам также нужно установить ширину и высоту холста равными ширине и высоте изображения, чтобы полностью соответствовать изображению.

let height = canvas.height = imgEl.height
let width = canvas.width = imgEl.width
let data = context.getImageData(0, 0, width, height).data

Я столкнулся с междоменной проблемой при первом тестировании:

Если картинка отличается от исходника, ее необходимо добавитьcrossorigin="anonymous"properties, а соответствующие разрешения должны быть открыты на стороне хранилища сервера.<img id="img" crossorigin="anonymous">

Обработка полученных данных о цвете

Запишем, какие данные мы получили:

Это массив с кучей данных, что это за данные? Давайте сначала посмотрим на MDN:

То есть посмотрите на первые четыре бита, чтобы сформировать данные в порядке RGBA:rgba(red, green, blue, 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;
}