Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过Javascript获取图像的平均颜色_Javascript_Image Manipulation - Fatal编程技术网

通过Javascript获取图像的平均颜色

通过Javascript获取图像的平均颜色,javascript,image-manipulation,Javascript,Image Manipulation,不确定这是否可行,但希望编写一个脚本,返回图像的平均hex或rgb值。我知道它可以在AS中完成,但希望能在JavaScript中完成 Javascript无法访问图像的单个像素颜色数据。至少,可能要等到html5。。。在这一点上,您可以将图像绘制到画布上,然后检查画布(可能,我自己从来没有这样做过)。我会说,通过HTML画布标记 你可以在@Georg的帖子中找到Opera dev的一段小代码: // Get the CanvasPixelArray from the given coordina

不确定这是否可行,但希望编写一个脚本,返回图像的平均
hex
rgb
值。我知道它可以在AS中完成,但希望能在JavaScript中完成

Javascript无法访问图像的单个像素颜色数据。至少,可能要等到html5。。。在这一点上,您可以将图像绘制到画布上,然后检查画布(可能,我自己从来没有这样做过)。

我会说,通过HTML画布标记

你可以在@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);
//从给定的坐标和维度获取CanvasPixelArray。
var imgd=context.getImageData(x,y,宽度,高度);
var pix=imgd.data;
//在每个像素上循环并反转颜色。
对于(变量i=0,n=pix.length;i

这将使用每个像素的R、G和B值反转图像。您可以轻松地存储RGB值,然后将红色、绿色和蓝色数组取整,最后将它们转换回十六进制代码。

好的,唯一的方法是使用

演示V2

注意,这只适用于同一域上的图像以及支持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;

}
函数getAverageRGB(imgEl){ var blockSize=5,//仅每5个像素访问一次 defaultRGB={r:0,g:0,b:0},//对于不支持的环境 canvas=document.createElement('canvas'), context=canvas.getContext&&canvas.getContext('2d'), 数据、宽度、高度、, i=-4, 长度, rgb={r:0,g:0,b:0}, 计数=0; 如果(!上下文){ 返回默认RGB; } 高度=canvas.height=imgEl.naturalHeight | | imgEl.offsetHeight | | imgEl.height; 宽度=canvas.width=imgEl.naturalWidth | | imgEl.offsetWidth | | imgEl.width; drawImage(imgEl,0,0); 试一试{ data=context.getImageData(0,0,宽度,高度); }捕获(e){ /*安全错误,img在不同域上*/ 返回默认RGB; } 长度=data.data.length; 而((i+=块大小*4)<长度){ ++计数; rgb.r+=data.data[i]; rgb.g+=data.data[i+1]; rgb.b+=data.data[i+2]; } //~~用于确定下限值 rgb.r=~~(rgb.r/计数); rgb.g=~~(rgb.g/计数); rgb.b=~~(rgb.b/计数); 返回rgb; }

对于IE,请查看。

首先:它可以在没有HTML5画布或SVG的情况下完成。
实际上,有人在没有画布或SVG的情况下,使用了

第二:您实际上可能根本不需要画布、SVG或以上任何一种 如果您只需要在客户端处理图像,而不修改它们,则不需要所有这些

您可以从页面上的img标记获取源地址,请求它-它很可能来自浏览器缓存-并将其作为来自Javascript的字节流进行处理。
您需要对图像格式有很好的了解。(上面的生成器部分基于libpng源,可能提供了一个很好的起点。)

“主色”很棘手。您要做的是比较颜色空间中每个像素和每个其他像素之间的距离(欧氏距离),然后找到颜色与每个其他颜色最接近的像素。那个像素是主色。平均颜色通常为泥浆

我希望我有MathML在这里向你们展示欧几里德距离。谷歌

在这里,我使用PHP/GD在RGB颜色空间中完成了上述执行:

然而,这在计算上非常昂贵。它会使您的系统在大图像上崩溃,如果您在客户端尝试,它肯定会使您的浏览器崩溃。我一直在努力重构我的执行,以: -将结果存储在查找表中,以便将来在每个像素上的迭代中使用。 -将大型图像划分为20px 20px的网格,以实现局部优势。 -使用x1y1和x1y2之间的欧几里德距离计算x1y1和x1y3之间的距离

如果你在这方面有进展,请告诉我。我很高兴看到它。我也会这样做

Canvas无疑是在客户端实现这一点的最佳方式。SVG不是,SVG是基于向量的。在我停止执行之后,下一步我要做的就是在画布上运行它(可能需要一个webworker来计算每个像素的总距离)

要考虑的另一件事是,RGB不是一个很好的颜色空间,因为RGB空间中颜色之间的欧几里德距离与视觉距离不是很接近。更好的颜色空间可能是LUV,但我还没有找到一个好的库,或者任何将RGB转换为LUV的算法


另一种完全不同的方法是在彩虹中对颜色进行排序,并建立一个带有容差的直方图来解释颜色的不同深浅。我没有尝试过这个,因为在彩虹中对颜色进行排序很困难,颜色直方图也是如此。下一步我可能会试试这个。同样,如果您在这里有任何进展,请告诉我。

我想我会发布一个我最近遇到的项目,以获得主色调:

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;

从图像中获取主色调或代表调色板的脚本。使用javascript和画布

其他提到和建议主色的解决方案在适当的上下文(“javascript”)中从未真正回答过这个问题。希望这个项目能帮助那些想做这件事的人。

这是关于“颜色量化”,它有几种方法,比如(改进的中值切割量化)或OQ(八叉树量化)。不同的方法
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;