Получите средний цвет изображения с помощью JavaScript

Не уверенный это возможно, но смотрящий на запись сценарий, который возвратил бы среднее число hex или rgb значение для изображения. Я знаю, что это может быть сделано в AS, но надеющийся делать это в JavaScript.

107
задан Brett DeWoody 17 January 2017 в 01:22
поделиться

5 ответов

AFAIK, единственный способ сделать это - использовать ...

DEMO V2 : http://jsfiddle.net/xLF38/818/

Обратите внимание, что это будет работать только с изображениями в том же домене и в браузерах, поддерживающих холст HTML5:

function getAverageRGB(imgEl) {

    var blockSize = 5, // only visit every 5 pixels
        defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs
        canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        data, width, height,
        i = -4,
        length,
        rgb = {r:0,g:0,b:0},
        count = 0;

    if (!context) {
        return defaultRGB;
    }

    height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
    width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;

    context.drawImage(imgEl, 0, 0);

    try {
        data = context.getImageData(0, 0, width, height);
    } catch(e) {
        /* security error, img on diff domain */
        return defaultRGB;
    }

    length = data.data.length;

    while ( (i += blockSize * 4) < length ) {
        ++count;
        rgb.r += data.data[i];
        rgb.g += data.data[i+1];
        rgb.b += data.data[i+2];
    }

    // ~~ used to floor values
    rgb.r = ~~(rgb.r/count);
    rgb.g = ~~(rgb.g/count);
    rgb.b = ~~(rgb.b/count);

    return rgb;

}

Для IE см. excanvas .

135
ответ дан 24 November 2019 в 03:35
поделиться

"Доминирующий цвет" сложно. Что вы хотите сделать, так это сравнить расстояние между каждым пикселем и каждым другим пикселем в цветовом пространстве (Евклидово расстояние), а затем найти пиксель, цвет которого ближе всего к любому другому цвету. Этот пиксель является доминирующим цветом. Обычно средний цвет грязи.

Хотел бы я иметь здесь MathML, чтобы показать вам евклидово расстояние. Поищи в Гугле.

Я выполнил описанное выше выполнение в цветовом пространстве RGB с помощью PHP / GD здесь: https://gist.github.com/cf23f8bddb307ad4abd8

Однако это очень дорого с вычислительной точки зрения. Это приведет к сбою вашей системы на больших изображениях и, безусловно, приведет к сбою вашего браузера, если вы попробуете его в клиенте. Я работал над рефакторингом своего выполнения, чтобы: - сохранять результаты в таблице поиска для будущего использования при итерации по каждому пикселю. - разделять большие изображения на сетки размером 20 пикселей 20 пикселей для локализованного доминирования . - использовать евклидово расстояние между x1y1 и x1y2 для определения расстояния между x1y1 и x1y3.

Пожалуйста, дайте мне знать, если вы добьетесь прогресса в этом направлении. Я был бы рад это увидеть. Я сделаю то же самое.

Canvas - определенно лучший способ сделать это в клиенте. SVG - нет, SVG - векторный. После того, как я завершу выполнение, следующее, что я хочу сделать, это запустить это на холсте (возможно, с веб-работником для расчета общего расстояния каждого пикселя).

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

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

49
ответ дан 24 November 2019 в 03:35
поделиться

Первое: это можно сделать без HTML5 Canvas или SVG.
На самом деле, кому-то только что удалось генерировать PNG-файлы на стороне клиента с помощью JavaScript, без canvas или SVG, используя схему URI данных.

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

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

.
15
ответ дан 24 November 2019 в 03:35
поделиться

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

4
ответ дан 24 November 2019 в 03:35
поделиться

Я бы сказал через тег HTML Canvas.

Вы можете найти здесь сообщение @Georg о небольшом коде разработчика Opera:

// Get the CanvasPixelArray from the given coordinates and dimensions.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

// Loop over each pixel and invert the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i  ] = 255 - pix[i  ]; // red
    pix[i+1] = 255 - pix[i+1]; // green
    pix[i+2] = 255 - pix[i+2]; // blue
    // i+3 is alpha (the fourth element)
}

// Draw the ImageData at the given (x,y) coordinates.
context.putImageData(imgd, x, y);

Он инвертирует изображение, используя значения R, G и B каждого пикселя. Вы можете легко сохранить значения RGB, затем округлить массивы Red, Green и Blue и, наконец, преобразовать их обратно в HEX-код.

9
ответ дан 24 November 2019 в 03:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: