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


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

11 91

11 ответов:

AFAIK, единственный способ сделать это с <canvas/>...

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

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

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.

решил, что я опубликую проект, с которым я недавно столкнулся, чтобы получить доминирующий цвет:

Цвета Вора

скрипт для захвата доминирующего цвета или репрезентативной цветовой палитры из изображения. Использует javascript и холст.

другие решения, упоминающие и предлагающие доминирующий цвет, никогда не отвечают на вопрос в правильном контексте ("в javascript"). Надеюсь, этот проект поможет тем, кто хочет сделать именно это.

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

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

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

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

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

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

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

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

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

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

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

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

// 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, затем округлить красные, зеленые и синие массивы и, наконец, преобразовать их обратно в шестнадцатеричный код.

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

недавно я наткнулся на плагин jQuery, который делает то, что я изначально хотел https://github.com/briangonzalez/jquery.adaptive-backgrounds.js в отношении получения доминирующего цвета из изображения.

речь идет о "цветном квантовании", которое имеет несколько подходов, таких как MMCQ (модифицированной срединной вырезать квантования) или ОК (восьмеричного дерева набора квантования). Другой подход использовать К-Означает для получения кластеров цветов.

Я собрал все вместе здесь, так как я нашел решение для tvOS где есть подмножество XHTML, которое не имеет <canvas/> элемент:

генерация доминирующих цветов для изображения RGB с помощью Поскольку

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

менее точный, но быстрый способ получить средний цвет изображения с datauri поддержка:

function get_average_rgb(img) {
    var context = document.createElement('canvas').getContext('2d');
    if (typeof img == 'string') {
        var src = img;
        img = new Image;
        img.setAttribute('crossOrigin', ''); 
        img.src = src;
    }
    context.imageSmoothingEnabled = true;
    context.drawImage(img, 0, 0, 1, 1);
    return context.getImageData(1, 1, 1, 1).data.slice(0,3);
}

Решение Все-В-Одном

Я бы лично комбината Цвета Вора вместе с модифицированная версия имя, цвет для получения более чем достаточного массива результатов доминирующего цвета для изображений.

пример:

рассмотрим следующее изображение:

enter image description here

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

let color_thief  = new ColorThief();
let sample_image = new Image();

sample_image.onload = () =>
{
    let result = ntc.name( '#' + color_thief.getColor( sample_image ).map( x =>
    {
        const hex = x.toString( 16 );
        return hex.length === 1 ? '0' + hex : hex;

    }).join( '' ) );

    console.log( result[0] ); // #F0C420     : Dominant HEX/RGB value of closest match
    console.log( result[1] ); // Moon Yellow : Dominant specific color name of closest match
    console.log( result[2] ); // #FFFF00     : Dominant HEX/RGB value of shade of closest match
    console.log( result[3] ); // Yellow      : Dominant color name of shade of closest match
    console.log( result[4] ); // false       : True if exact color match
};

sample_image.crossOrigin = 'anonymous';
sample_image.src         = document.getElementById( 'sample-image' ).src;