通过Javascript获取图像的平均颜色
不知道这是可能的,但希望编写一个脚本,将返回图像的平均hex
或rgb
值。 我知道它可以在AS中完成,但希望在JavaScript中做到这一点。
AFAIK,唯一的方法是使用<canvas/>
…
演示 : http : //jsfiddle.net/xLF38/
DEMO V2 : http : //jsfiddle.net/xLF38/818/
原始演示在代码中有一个小错误,这在V2中是固定的
请注意,这仅适用于支持HTML5canvas的相同网域和浏览器中的图片:
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和canvas。
其他提到并提示主色的解决scheme从来没有在正确的上下文中回答这个问题(“在javascript中”)。 希望这个项目能够帮助那些想要这样做的人。
“主色”是棘手的。 你想要做的是比较每个像素和其他每个像素在颜色空间(欧几里德距离)之间的距离,然后find颜色与其他颜色最接近的像素。 那个像素是主色。 平均颜色通常是泥。
我希望在这里有MathML给你看欧几里德距离。 去谷歌上查询。
我已经在这里使用PHP / GD在RGB色彩空间完成了上面的执行: https : //gist.github.com/cf23f8bddb307ad4abd8
然而,这在计算上非常昂贵。 它会使你的系统崩溃在大的图像上,如果你在客户端尝试它,肯定会崩溃你的浏览器。 我一直在努力重构我的执行,以便: – 将结果存储在查找表中,以便将来在每个像素的迭代中使用。 – 将大的图像分割成20像素×20像素的网格以获得局部优势。 – 使用x1y1和x1y2之间的欧式距离来计算x1y1和x1y3之间的距离。
如果你在这方面取得进展,请让我知道。 我会很高兴看到它。 我也会这样做。
canvas绝对是在客户端做到这一点的最佳方式。 SVG不是,SVG是基于vector的。 在执行完后,接下来我要做的就是在canvas上运行(也许每个像素的总距离计算都有一个webworker)。
另一件要考虑的事情是,RGB不是一个好的颜色空间,因为RGB空间中的颜色之间的欧式距离并不是非常接近视觉距离。 一个更好的颜色空间可能是LUV,但我还没有find一个好的库,或者任何将RGB转换为LUV的algorythims。
一个完全不同的方法是将你的颜色分类为彩虹,并build立一个宽容的直方图来考虑颜色的不同阴影。 我还没有尝试过,因为彩虹中的颜色sorting很难,颜色直方图也是如此。 我可能会尝试下一个。 再次,让我知道,如果你在这里取得任何进展。
首先:可以不使用HTML5 Canvas或SVG。
实际上,有人只是设法使用JavaScript生成客户端PNG文件 , 而不使用canvas或SVG,使用数据URIscheme 。
其次:你可能实际上不需要Canvas,SVG或者上面的任何一个。
如果您只需要在客户端处理图像而不修改它们,则不需要这些。
您可以从页面上的img标签获取源地址,为其创buildXHR请求(很可能来自浏览器caching),并将其作为来自Javascript的字节stream进行处理。
你需要对图像格式有一个很好的理解。 (上面的生成器部分基于libpng源,可能会提供一个很好的起点。)
我会通过HTMLcanvas标签说。
你可以在这里find一篇由@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值,然后将红色,绿色和蓝色数组四舍五入,最后将其转换回hex代码。
Javascript无法访问图像的单个像素颜色数据。 至less,也许直到html5 …在这一点上,你可以画一个图像到一个canvas,然后检查canvas(也许,我从来没有自己做过)。
我最近遇到了一个jQuery插件,它做了我最初想要的https://github.com/briangonzalez/jquery.adaptive-backgrounds.js关于从图像中获取统治的颜色。;
这是关于“颜色量化”,有几种方法,如MMCQ (修正中值切割量化)或OQ(八度量化)。 不同的方法使用K-Means来获得颜色簇。
我把所有的东西放在一起,因为我正在为tvOS
find一个有XHTML子集的解决scheme,它没有<canvas/>
元素:
使用XMLHttpRequest生成RGB图像的主色
有一个在线工具pickimagecolor.com ,可以帮助你find图像的平均或主导颜色。你只需要从计算机上传图像,然后点击图像。 它给出了HEX,RGB和HSV的平均颜色。 它还可以find与可供select的颜色相匹配的色调。 我多次使用过它。