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

时间:2009-12-20 14:42:32

标签: javascript jquery colors selection color-picker

我正在寻找一个“ eyedropper ”工具,它为我提供了鼠标光标所在像素的十六进制值,用于CMS。

对于Firefox,有一个非常好的ColorZilla扩展名。但是,它当然只是FF,我真的很想将该工具与CMS一起交付。

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

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

我也对任何可以执行ColorZilla操作的IE特定解决方案感兴趣 - 我可以只支持IE和FF,但跨浏览器解决方案当然是理想的。

9 个答案:

答案 0 :(得分:69)

使用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);

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

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

答案 1 :(得分:14)

使用一种称为浏览器计时攻击的技术,可以(确定)确定任何像素的颜色,即使在iframe上也是如此。

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

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

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

答案 2 :(得分: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>

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

答案 3 :(得分:7)

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

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

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

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

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

答案 4 :(得分:4)

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

要截取屏幕截图,您可以使用Selenium IDE之类的here

希望它有所帮助。

答案 5 :(得分:4)

查看新输入[type = color] HTML5元素:http://www.w3.org/TR/html-markup/input.color.htmlhttp://demo.hongkiat.com/html5-form-input-type/index2.html

现在它至少在Chrome中运行(在Ubuntu中测试,也适用于Windows)。它启动操作系统提供的颜色选择对话框 。如果此对话框中有吸管(适用于Gnome),则可以从屏幕上的任意位置选择颜色。不是跨浏览器,而是基于标准的清洁。

答案 6 :(得分:3)

添加到之前的答案 -

想到这个问题的一种方法是,您希望能够对1px xpx区域进行屏幕捕获。捕获屏幕区域的相当常见的技术(例如来自基于Web的错误报告系统)是使用签名的Java小程序和java.awt.Robot来捕获图片。如果您对小程序进行签名,您的用户将会收到“您信任此应用程序”对话框(“始终信任来自此发布者的应用程序”复选框),然后就可以使用该工具了。

然后,您可以使用LiveConnect将结果传递给JavaScript(文档很旧,但Java applet仍支持此功能),或者您可以将结果发布到服务器。同样,您可以从JavaScript调用Java applet。

答案 7 :(得分:3)

作为安全预防措施,您无法使用Javascript捕获屏幕像素(因此开发人员无法拍摄您的个人数据的快照),但您可以在Flash中执行此操作 - 您可以使用Flash获取Flash容器中的像素数据flash.display.BitmapData类。

查看http://www.sephiroth.it/tutorials/flashPHP/print_screen/ - 我在基于Flash的WYSYWIG项目中使用它将图像保存到LAMP(PHP)服务器。

使用Flash的问题在于iOS设备本身不支持它,这些设备现在非常流行,值得开发。闪光灯正在沿着灯管走下去。

如果所有访问者都拥有支持canvas标记和JavaScript的最新Web浏览器,那么基于画布的方法肯定是一个很好的方法。

答案 8 :(得分:2)

没有内置的DOM方法来统一获取特定像素位置的DOM元素(图像或<canvas>除外)的颜色。

因此,为了做到这一点,我们必须使用HTML2CanvasDOM Panda这样的内容来获取我们网站的“屏幕截图”,获取用户的点击位置,并获取其像素颜色在那个特定位置的“截图”。

使用HTML2Canvas(版本0.5.0-beta3),您可以执行以下操作:

// Take "screenshot" using HTML2Canvas
var screenshotCanvas,
    screenshotCtx,
    timeBetweenRuns = 10,
    lastTime = Date.now();
function getScreenshot() {
    // Limit how soon this can be ran again
    var currTime = Date.now();
    if(currTime - lastTime > timeBetweenRuns) {
        html2canvas(document.body).then(function(canvas) {
            screenshotCanvas = canvas;
            screenshotCtx = screenshotCanvas.getContext('2d');
        });
        lastTime = currTime;
    }
}
setTimeout(function() { // Assure the initial capture is done
    getScreenshot();
}, 100);

// Get the user's click location
document.onclick = function(event) {
    var x = event.pageX,
        y = event.pageY;

    // Look what color the pixel at the screenshot is
    console.log(screenshotCtx.getImageData(x, y, 1, 1).data);
}


// Update the screenshot when the window changes size
window.onresize = getScreenshot;

Demo

相关问题