0

给定一个 RGB 值和一个图像。我想要实现的是使用 RGB 输入为图像着色,我想用我的 RGB 值替换图像的主要颜色。实现这一目标的最简单方法是什么?

4

2 回答 2

0

使用 colorThief 之类的脚本从图像中获取主色:

https://github.com/lokesh/color-thief

然后使用这种代码将主要颜色替换为您想要的颜色

这是未经测试的代码...可能需要进行一些调整:

function recolor(image,predominantRed,predominantGreen,predominantBlue){

    // get the image dimensions
    var w=image.width;
    var h=image.height;

    // set the canvas dimensions to the image dimensions
    canvas.width=w;
    canvas.height=h;

    // draw the image to the canvas
    context.drawImage(image,0,0);

    // get the canvas' pixel array
    var imageData = context.getImageData(0,0,w,h);
    var data = imageData.data;

    // loop through the pixel array
    // replace any predominant color with your new color
    for(var i=0; i<data.length; i+=4) {
        var red=data[i];
        var green=data[i+1];
        var blue=data[i+2];
        if(red==predominantRed 
              && green==predominantGreen
              && blue==predominantBlue){
            data[i]  = yourRed;
            data[i+1]= yourGreen;
            data[i+2]= yourBlue;
        }
    }

    // put the modified pixels back on the canvas
    context.putImageData(imageData, x, y);
}
于 2013-09-10T03:47:18.927 回答
0

您必须通过循环遍历像素数组缓冲区并计算每种颜色的实例来创建统计信息。

然后选择计数最高的实例。

在线演示在这里

这样做的一种方法如下(未优化,但为了举例):

var rgb = {};

/// get image buffer

for(var i = 0; i < len; i += 4) {

    /// get components
    r = buffer[i];
    g = buffer[i + 1];
    b = buffer[i + 2];

    /// create a key based on components to identify color
    color = [r,g,b].join();

    /// count this color
    rgb[color] = (rgb[color] || 0) + 1;
}

这将生成一个具有所有现有颜色和每种颜色计数的对象。所以下一步是找到计数最高的那个:

function getDominantColor() {

    var max = -1,                /// max count
        color = null,            /// the actual color
        keys = Object.keys(rgb), /// get keys of rgb object
        len = keys.length,       /// cache length
        v,                       /// value (color) based on key
        i = 0;

    for(;i < len; i++) {

        /// get count for this key
        v = rgb[keys[i]];

        /// if higher than previous, replace with this as max
        if (v > max) {
            max = v;
            color = keys[i];
        }
    }

    /// convert string to array
    color = color.split(',');

    /// return array with integer values
    return [parseInt(color[0], 10),
            parseInt(color[1], 10),
            parseInt(color[2], 10)]
}

现在您可以再次检查像素缓冲区并用新颜色替换颜色:

for(i = 0; i < len; i += 4) {
    r = buffer[i];
    g = buffer[i + 1];
    b = buffer[i + 2];

    if (r === color[0] &&
        g === color[1] &&
        b === color[2]) {

        /// set new color, red here for example
        buffer[i] = 255;
        buffer[i + 1] = 0;
        buffer[i + 2] = 0;
    }
}

需要注意的事项:主色不一定非要在视觉上占主导地位。可能有许多看起来相似但实际上并不相似的颜色。因此,解决此问题的方法是对要替换的颜色实施容差,如果这是您的次要目标。

于 2013-09-10T03:48:10.483 回答