Вот живой пример.

В этом уроке я расскажу, как построить средний цвет видео за кадром с помощью D3 и Vue. Я также покажу вам, как использовать веб-работника для расчета цвета.

Вот обзор того, как это будет работать: мы создадим элемент холста, который будет скрыт. Когда видео воспроизводится, мы напишем функцию с использованием requestAnimationFrame, которая будет рисовать текущий видеокадр в контексте элементов холста. Затем мы получим данные изображения с холста и передадим их Web Worker, который затем вычислит среднее значение RGB для холста. Затем Web Worker отправит сообщение обратно компоненту D3, который нанесет на график значения красного, синего и зеленого цветов, а также комбинированный средний цвет. Вот как это будет выглядеть:

Вот репо для всего учебника. Если вы хотите клонировать его, просто не забудьте запустить npm install перед запуском сервера разработки.

Установка

Как и в большинстве этих руководств, мы будем использовать webpack для создания и запуска однофайловых компонентов. Он также понадобится нам для загрузки нашего веб-воркера. Убедитесь, что у вас установлен vue-cli (запустите npm install -g vue-cli, если у вас его нет). Затем из каталога ваших проектов запустите:

vue init webpack video-color-plot

Для этого вам не понадобится vue-router.

Чтобы заставить воркера работать, нам нужно установить worker-loader и указать нашей базовой конфигурации веб-пакета использовать этот загрузчик для любого файла, который заканчивается на worker.js.

npm install --save worker-loader

Затем в build/webpack.base.conf.js добавьте это в массив правил для модулей webpack:

{
   test: /\worker\.js$/,
   loader: 'worker-loader',
   include: [resolve('src'), resolve('test')]
}

Это позволит вам импортировать воркеров прямо в компонент Vue. Теперь можно начинать!

Компонент приложения

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

Когда основной компонент установлен, мы устанавливаем размер холста того же размера, что и видео. Мы также создали onmessage функцию, которая будет обновлять состояние компонентов с помощью результата вычисления цвета рабочего (объяснено ниже).

Основная часть работы выполняется методом drawCanvas. Здесь мы используем requestAnimationFrame для повторного вызова метода drawCanvas настолько быстро, насколько позволяет браузер.

Фактически мы ограничиваем выполнение рисования холста 1/3 от частоты кадров видео. Я поигрался с этим значением, чтобы получить наилучшие результаты. Вы можете прочитать больше об этой технике здесь, спасибо Адди Османи.

Давайте посмотрим на веб-воркера.

Работник

Основная задача исполнителя - принять данные, которые imageData получены с холста, и просмотреть их, чтобы получить средние значения красного, зеленого и синего цветов. Я не изобретал эту технику (подробнее о ней вы можете прочитать в этой отличной статье о переполнении стека).

В качестве альтернативы вы можете использовать что-то вроде ColorThief для этого. По сути, imageData из элемента холста возвращается как Uint8ClampedArray (подробнее об этом вы можете прочитать здесь), и мы выполняем цикл до тех пор, пока наш итератор i не станет больше, чем длина данных. Когда расчет произведен, он отправляет сообщение обратно основному компоненту, который затем обновляет состояние этого компонента. Когда состояние обновляется, компонент Chart будет повторно визуализирован, отображая новый цвет в текущем кадре. Давайте посмотрим на компонент Chart.

График

Здесь происходит вся магия D3. Когда компонент установлен, мы настраиваем нашу диаграмму. На диаграмме есть ось xAxis (представляющая длину видео в кадрах) и yAxis (в диапазоне от 0 до 256, что представляет диапазон возможных значений для красного, синего и зеленого). В D3 мы рисуем ось, используя длину в пикселях элемента svg, но область оси не в пикселях, а в кадрах (xAxis) или значениях rgb (yAxis). D3 позволяет легко переводить абстрактные данные (номер кадра вместе с данными RGB) в визуальное представление (точка на нанесенной диаграмме) с помощью шкал. Создаем шкалу (строки 94,95) и к каждой применяем домен (строки 98, 99). Домен - это просто диапазон возможных значений.

После настройки диаграммы мы наблюдаем за изменением значения frame prop и затем вызываем updateChart. Опора averageColor - это объект с ключами r, g и b. Мы используем map lodash для сопоставления объекта и для каждого ключа получаем значение (число от 0 до 256) и применяем его к оси y. D3 берет это значение и переводит его в пиксель, чтобы знать, где на самом деле нарисовать круг.

Заключение

Вот и все. Работать с D3 внутри Vue действительно приятно, и для этого не требуется никаких волшебных настроек. Попробуйте это сделать с разными видео и посмотрите, какие результаты вы получите!

Рамзи - разработчик полного цикла JavaScript в компании по анализу данных в Спрингфилде, штат Вирджиния. Вы можете подписаться на него в твиттере или гитхабе. Ему нравится, когда ты это делаешь.