JavaScript 滴管(告诉鼠标光标下像素的颜色)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1936021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript eyedropper (tell color of pixel under mouse cursor)
提问by Pekka
I am looking for an "eyedropper" tool, that gives me the hex value of the pixel the mouse cursor is under, in JavaScript for a CMS.
我正在寻找一个“吸管”工具,它在 CMS 的 JavaScript 中为我提供鼠标光标所在像素的十六进制值。
For Firefox, there is the excellent ColorZillaextension that does exactly that. However, it's FF only of course, and I would really like to deliver the tool along with the CMS.
对于 Firefox,有出色的ColorZilla扩展程序可以做到这一点。然而,它当然只是 FF,我真的很想与 CMS 一起提供该工具。
A dutch developer has had the very clever ideaof using a combination of Ajax and PHP's imagecolorat()to find out the Pixel colour on an image. But that limits the range to images I can access server side, and I'm really dreaming of a universal tool.
一位荷兰开发人员有一个非常聪明的想法,即结合使用 Ajax 和 PHPimagecolorat()来找出图像上的像素颜色。但这限制了我可以访问服务器端的图像的范围,我真的梦想有一个通用工具。
I will work with one of these approaches, but would much prefer a cross-browser, Javascript or Flash based way that requires no server-side fiddling and no installing of extensions.
我将使用这些方法之一,但更喜欢跨浏览器、基于 Javascript 或 Flash 的方式,不需要服务器端摆弄和安装扩展。
I am also interested in any IE specific solutions that do what ColorZilla can do - I could live with supporting IE and FF only, though a cross browser solution would of course be ideal.
我也对做 ColorZilla 可以做的任何 IE 特定解决方案感兴趣 - 我可以只支持 IE 和 FF,尽管跨浏览器解决方案当然是理想的。
回答by Eli Grey
It's not possible with JavaScript as it goes against cross-domain security. It would be very bad if you knew what pixels made up the image, http://some-other-host/yourPassword.png. You can only tell the color of the pixel under the mouse if either the mouse is over a canvas or an image element of the same domain (or an image element of another domain which is served with an Access-Control-Allow-Origin: *header). In the case of the canvas, you would do canvasElement.getContext('2d').getImageData(x, y, 1, 1).data. In the case of the images, you would have to draw them to a canvas with:
使用 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);
And then just use the previous method explained for canvases. If you must be able to convert to various representations of color values, try my color.jslibrary.
然后只需使用先前为画布解释的方法。如果您必须能够转换为颜色值的各种表示,请尝试我的color.js库。
Also, you're never going to be able to support IE <9 (that's assuming that IE9 supports canvas) and using Flash won't help as it can't read the pixel data of the document either.
此外,您永远无法支持 IE <9(假设 IE9 支持画布)并且使用 Flash 也无济于事,因为它也无法读取文档的像素数据。
回答by Fran?ois Zaninotto
Using a technique called Browser Timing Attack, it is possible to (sort of) determine the color of any pixel, even on iframes.
使用称为Browser Timing Attack的技术,可以(某种程度上)确定任何像素的颜色,即使在 iframe 上也是如此。
Basically, this technique measures the time to render an SVG filter on an element, rather than the color itself (requestAnimationFrame()allows to measure time with a much better accuracy than setTimeout()). Depending on the current pixel color, the filter takes more or less time to apply. This makes it possible to determine if a pixel is the same color as a known color - for instance black or white.
基本上,这种技术测量在元素上渲染 SVG 过滤器的时间,而不是颜色本身(requestAnimationFrame()允许以比 更好的精度测量时间setTimeout())。根据当前的像素颜色,过滤器需要或多或少的时间来应用。这使得可以确定像素是否与已知颜色相同 - 例如黑色或白色。
More details in this white paper (pdf): http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf
本白皮书 (pdf) 中的更多详细信息:http: //www.contextis.com/documents/2/Browser_Timing_Attacks.pdf
By the way: yes, this is a browser security hole, but I don't see how browser vendors can patch it.
顺便说一句:是的,这是一个浏览器安全漏洞,但我不知道浏览器供应商如何修补它。
回答by ebragaparah
Merging various references found here in StackOverflow and in other sites, I did so using javascript and JQuery:
合并在 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>
This is my complete solution.. Here I only used canvas and one image, but if you need to use <map>over the image, it's possible too. I hope I have helped.
这是我的完整解决方案。这里我只使用了画布和一张图片,但如果您需要使用<map>图片,也可以。我希望我有所帮助。
回答by rdmueller
I do agree with the very detailed answer provided by Elijah. In addition, I would say that you don't need the canvas when it comes to images. As you stated yourself, you have those images available from within php and can do the color-query on the server.
我确实同意以利亚提供的非常详细的答案。此外,我会说在图像方面您不需要画布。正如您自己所说,您可以从 php 中获得这些图像,并且可以在服务器上进行颜色查询。
I would suggest that you handle this problem with an external tool - this makes it even browser indepedent (but OS dependent): write a small tool (for instance in c#) which does the color query for you, is invoked with a shortcut and submits the color to your server. Make the tool available as download on your CMS.
我建议您使用外部工具处理这个问题 - 这使它甚至与浏览器无关(但依赖于操作系统):编写一个小工具(例如在 c# 中)为您执行颜色查询,使用快捷方式调用并提交服务器的颜色。使该工具可在您的 CMS 上下载。
Another aproach I used for a CMS was to "steal" colors by parsing the CSS: the use case was to make the colors of an already existing web site available as color palette to my application:
我用于 CMS 的另一种方法是通过解析 CSS 来“窃取”颜色:用例是将现有网站的颜色作为调色板提供给我的应用程序:
- I asked the user to provide a URL from the target system - mostly the company's home page
- I parsed the page to find all color definitions in all inline styles and linked styles
- (you can easily extend this to all referenced images)
- the result was a nice color palette with all coporate colors to choose from
- 我要求用户提供来自目标系统的 URL——主要是公司的主页
- 我解析了页面以找到所有内联样式和链接样式中的所有颜色定义
- (您可以轻松地将其扩展到所有引用的图像)
- 结果是一个漂亮的调色板,可以选择所有公司的颜色
Maybe that's also a solution for your CMS?
也许这也是您的 CMS 的解决方案?
回答by tema
See new input[type=color] HTML5 element: http://www.w3.org/TR/html-markup/input.color.html, http://demo.hongkiat.com/html5-form-input-type/index2.html.
查看新的 input[type=color] HTML5 元素:http: //www.w3.org/TR/html-markup/input.color.html, http://demo.hongkiat.com/html5-form-input-type /index2.html。
Now it works at least in Chrome (tested in Ubuntu, should work for Windows too). It launches color-select dialog provided by operating system. If there is an eyedropper in this dialog (it is for Gnome), then it's possible to pick a color from any point on your screen. Not cross-browser yet, but clean and standards-based.
现在它至少适用于 Chrome(在 Ubuntu 中测试,也适用于 Windows)。它启动操作系统提供的颜色选择对话框。如果此对话框中有一个滴管(用于 Gnome),则可以从屏幕上的任何点选取一种颜色。还不是跨浏览器,但干净且基于标准。
回答by jbochi
I don't know if this is feasible, but if your pages are static you could save an image screenshot of each one of them (or maybe one for each browser/screen resolution? ) and then use AJAX to send the cursor coordinates to the server and return the pixel color with PHP's imagecolorat().
我不知道这是否可行,但如果您的页面是静态的,您可以保存每个页面的图像屏幕截图(或者每个浏览器/屏幕分辨率各一个?),然后使用 AJAX 将光标坐标发送到服务器并使用 PHP 的imagecolorat().
To take the screenshots, you could use Selenium IDElike described here.
要截取屏幕截图,您可以使用此处描述的Selenium IDE。
Hope it helps.
希望能帮助到你。
回答by William Billingsley
To add to the previous answers --
添加到以前的答案-
One way of thinking of this problem is that you want to be able to do a screen-capture of a 1px by 1px region. A fairly common technique for capturing screen regions (for instance from within Web-based bug-reporting systems) is to use a signed Java applet and java.awt.Robot to capture the picture. If you sign the applet, your users will get a "do you trust this app" dialog (with an "always trust apps from this publisher" checkbox) and then will be able to use the tool.
考虑此问题的一种方式是您希望能够对 1px x 1px 区域进行屏幕捕获。捕获屏幕区域(例如从基于 Web 的错误报告系统中)的一种相当常见的技术是使用签名的 Java 小程序和 java.awt.Robot 来捕获图片。如果您签署小程序,您的用户将收到“您是否信任此应用程序”对话框(带有“始终信任来自此发布者的应用程序”复选框),然后将能够使用该工具。
You can then pass the result out to JavaScript using LiveConnect (the docs are old, but Java applets still support this), or you can post it to your server. Similarly, you can call into the Java applet from JavaScript.
然后,您可以使用 LiveConnect 将结果传递给 JavaScript(文档已经过时,但 Java 小程序仍然支持此功能),或者您可以将其发布到您的服务器。同样,您可以从 JavaScript 调用 Java 小程序。
回答by supershwa
As a security precaution you can't capture screen pixels with Javascript (so developers can't take snapshots of your personal data), but you CAN do it in Flash -- you can get pixel data within the Flash container using the flash.display.BitmapData class.
作为安全预防措施,您无法使用 Javascript 捕获屏幕像素(因此开发人员无法拍摄您的个人数据的快照),但您可以在 Flash 中执行此操作——您可以使用 flash.display 在 Flash 容器中获取像素数据.BitmapData 类。
Check out http://www.sephiroth.it/tutorials/flashPHP/print_screen/-- I've used it in Flash-based WYSYWIG projects to save images to a LAMP (PHP) server.
查看http://www.sephiroth.it/tutorials/flashPHP/print_screen/——我在基于 Flash 的 WYSYWIG 项目中使用它来将图像保存到 LAMP (PHP) 服务器。
The problem with using Flash is that it's not natively supported on iOS devices, which are extremely popular now and worth developing for. Flash is on its way down the tubes.
使用 Flash 的问题在于它在 iOS 设备上不受本机支持,iOS 设备现在非常流行并且值得开发。闪光灯正在沿着管子向下移动。
The canvas-based method will certainly be a good one provided all of your visitors have up-to-date web browsers that support the canvas tag and JavaScript.
如果您的所有访问者都拥有支持画布标签和 JavaScript 的最新 Web 浏览器,那么基于画布的方法肯定会是一个很好的方法。
回答by Zach Saucier
There is no built in DOM method to generically get the color of a DOM element (other than images or a <canvas>) at a particular pixel location.
没有内置的 DOM 方法可以<canvas>在特定像素位置一般获取 DOM 元素(图像或 a除外)的颜色。
Thus, in order to do this, we must use something like HTML2Canvasor DOM Pandato take a "screenshot" of our website, get the user's click location, and get the pixel color of the "screenshot" at that particular location.
因此,为了做到这一点,我们必须使用HTML2Canvas或DOM Panda 之类的东西来拍摄我们网站的“屏幕截图”,获取用户的点击位置,并获取该特定位置的“屏幕截图”的像素颜色。
Using HTML2Canvas (version 0.5.0-beta3) you can do something like this:
使用 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;

