JavaScript吸管(告诉鼠标光标下的像素颜色)

Pek*_*ica 66 javascript jquery color-picker colors selection

我正在寻找一个" 吸管 "工具,它给出了鼠标光标所在像素的十六进制值,用于CMS的JavaScript.

对于Firefox,有一个非常出色的ColorZilla扩展.但是,它当然只是FF,我真的很想将这个工具与CMS一起提供.

荷兰开发人员有一个非常聪明的想法,即使用Ajax和PHP的组合imagecolorat()来查找图像上的Pixel颜色.但这限制了我可以访问服务器端的图像的范围,我真的梦想着一个通用的工具.

我将使用其中一种方法,但更喜欢基于跨浏览器,基于Javascript或Flash的方式,不需要服务器端摆弄和不安装扩展.

我也对任何可以做ColorZilla可以做的IE特定解决方案感兴趣 - 我只能支持IE和FF,虽然跨浏览器解决方案当然是理想的.

Eli*_*rey 74

使用JavaScript是不可能的,因为它违反了跨域安全性.如果你知道像素构成了什么像素,那将是非常糟糕的http://some-other-host/yourPassword.png.如果鼠标位于画布上,或者同一域的图像元素(或者带有Access-Control-Allow-Origin: *标题的另一个域的图像元素),则只能告诉鼠标下像素的颜色.在画布的情况下,你会这样做canvasElement.getContext('2d').getImageData(x, y, 1, 1).data.对于图像,您必须将它们绘制到具有以下内容的画布:

var canvas = document.createElement("canvas");
canvas.width = yourImageElement.width;
canvas.height = yourImageElement.height;
canvas.getContext('2d').drawImage(yourImageElement, 0, 0);
Run Code Online (Sandbox Code Playgroud)

然后只需使用前面为画布解释的方法.如果您必须能够转换为颜色值的各种表示,请尝试我的color.js库.

此外,你永远不会支持IE <9(假设IE9支持画布),并且使用Flash也无济于事,因为它无法读取文档的像素数据.

  • 关于安全性的有趣方面,并感谢Canvas角度.但是,我只能访问我的域中的像素. (4认同)
  • @danross,js 没有执行脚本的跨沙箱访问权限(除非获得明确许可),没有理由不能将 api 限制为来自同一安全沙箱内的帧的颜色值。 (2认同)

Fra*_*tto 15

使用称为浏览器定时攻击的技术,即使在iframe上也可以(排序)确定任何像素的颜色.

基本上,这种技术测量在元素上渲染SVG滤镜的时间,而不是颜色本身(requestAnimationFrame()允许以比精度更高的精度测量时间setTimeout()).根据当前的像素颜色,过滤器需要或多或少的时间来应用.这使得可以确定像素是否与已知颜色相同 - 例如黑色或白色.

本白皮书中的更多细节(pdf):http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

顺便说一句:是的,这是一个浏览器安全漏洞,但我不知道浏览器供应商如何修补它.


ebr*_*rah 11

合并在StackOverflow和其他站点中找到的各种引用,我使用javascript和JQuery:

<html>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script src="jquery.js"></script>
<script type="text/javascript">
    window.onload = function(){
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');
        var img = new Image();
        img.src = 'photo_apple.jpg';
        context.drawImage(img, 0, 0);
    };

    function findPos(obj){
    var current_left = 0, current_top = 0;
    if (obj.offsetParent){
        do{
            current_left += obj.offsetLeft;
            current_top += obj.offsetTop;
        }while(obj = obj.offsetParent);
        return {x: current_left, y: current_top};
    }
    return undefined;
    }

    function rgbToHex(r, g, b){
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
    }

$('#myCanvas').click(function(e){
    var position = findPos(this);
    var x = e.pageX - position.x;
    var y = e.pageY - position.y;
    var coordinate = "x=" + x + ", y=" + y;
    var canvas = this.getContext('2d');
    var p = canvas.getImageData(x, y, 1, 1).data;
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    alert("HEX: " + hex);
});
</script>
<img src="photo_apple.jpg"/>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这是我的完整解决方案..在这里我只使用了画布和一个图像,但是如果你需要使用<map>图像,它也是可能的.我希望我有所帮助.

  • 如何使用滴管允许从任何地方获取颜色? (2认同)

rdm*_*ler 7

我同意以利亚提供的非常详细的答案.另外,我会说在图像方面你不需要画布.正如您所说,您可以从php中获得这些图像,并且可以在服务器上进行颜色查询.

我建议您使用外部工具处理此问题 - 这使得它甚至浏览器独立(但依赖于操作系统):编写一个小工具(例如在c#中)为您执行颜色查询,使用快捷方式调用并提交服务器的颜色.在CMS上下载该工具.

我用于CMS的另一个方法是通过解析CSS来"窃取"颜色:用例是将现有网站的颜色作为我的应用程序的调色板:

  • 我要求用户提供目标系统的URL - 主要是公司的主页
  • 我解析了页面以查找所有内联样式和链接样式中的所有颜色定义
  • (您可以轻松地将其扩展到所有引用的图像)
  • 结果是一个漂亮的调色板,所有的coporate颜色可供选择

也许这也是CMS的解决方案?


Bor*_*ipt 7

Chrome Canary 现在支持 EyeDropper API!

更新:Chrome 95+ 支持

https://www.chromestatus.com/feature/6304275594477568

我相信我们很快就能在所有流行的浏览器中看到它。

基本上,它将把用户的光标更改为放大镜,并让他选择页面上的任何像素(适用于图像、视频和 iframe)。

const eyeDropper = new EyeDropper()

async function useEyeDropper() {
  try {
    const selectedColor = await eyeDropper.open()
    console.log(selectedColor) // { sRGBHex: '#008080' }
  } catch (err) {
    console.log('eye dropper cancelled')
  }
}

someTriggerEl.addEventListener('click', () => {
  useEyeDropper();
})
Run Code Online (Sandbox Code Playgroud)

如果您不太了解 async/await:

const eyeDropper = new EyeDropper()

someTriggerEl.addEventListener('click', () => {
  eyeDropper.open().then(selectedColor => {
    console.log(selectedColor) // { sRGBHex: '#008080' }
  }).catch(() => {
    console.log('eye dropper cancelled')
  })
})
Run Code Online (Sandbox Code Playgroud)

我对这个功能非常兴奋


jbo*_*chi 5

我不知道这是否可行,但是如果您的页面是静态的,您可以保存每个页面的图像屏幕截图(或者每个浏览器/屏幕分辨率各一个?),然后使用 AJAX 将光标坐标发送到服务器并使用 PHP 的imagecolorat().

要截取屏幕截图,您可以使用此处描述的Selenium IDE

希望能帮助到你。


小智 5

参见新的input [type = color] HTML5元素:http : //www.w3.org/TR/html-markup/input.color.html,http : //demo.hongkiat.com/html5-form-input-type /index2.html

现在,它至少可以在Chrome中运行(在Ubuntu中经过测试,也应该适用于Windows)。它启动操作系统提供的颜色选择对话框。如果此对话框中有一个吸管(用于Gnome),则可以从屏幕上的任意位置选择一种颜色。尚未跨浏览器,但整洁且基于标准。

  • 不幸的是,Chrome 最近更新了他们的表单控件设计,并且他们的新颜色选择器没有吸管。 (3认同)