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

我正在寻找一个“ 滴管”工具,它给我的像素十六进制值的鼠标光标下,在 JavaScript 的 CMS。

对于 Firefox 来说,有一个优秀的 < strong > ColorZilla 扩展可以做到这一点。然而,它只是 FF 当然,我真的很想交付的工具以及 CMS。

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

我将使用其中的一种方法,但是我更喜欢一种跨浏览器、基于 Javascript 或 Flash 的方法,这种方法不需要服务器端的修改,也不需要安装扩展。

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

64837 次浏览

使用 JavaScript 是不可能的,因为它违背了跨域安全性。如果你知道是什么像素构成了图像,那将是非常糟糕的。只有当鼠标位于画布上或同一域的图像元素(或与 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 也没用,因为它无法读取文档的像素数据。

我同意以利亚提供的非常详细的答案。此外,我想说的是,当涉及到图像时,您不需要画布。正如您自己所说的,您可以从 php 中获得这些图像,并且可以在服务器上进行颜色查询。

我建议你用一个外部工具来解决这个问题——这使得它甚至可以独立于浏览器(但是依赖于操作系统) : 编写一个小工具(例如在 c # 中)为你做颜色查询,用快捷方式调用并提交颜色到你的服务器。在您的 CMS 上下载该工具。

我在 CMS 中使用的另一种方法是通过解析 CSS 来“窃取”颜色: 用例是将已经存在的网站的颜色作为调色板提供给我的应用程序:

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

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

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

要截屏,您可以使用 硒化物,就像描述的 给你那样。

希望能有帮助。

为了补充前面的答案——

解决这个问题的一种方法是,希望能够对1px 乘以1px 的区域进行屏幕截图。捕获屏幕区域(例如在基于 Web 的 bug 报告系统中)的一种相当常见的技术是使用签名的 Javaapplet 和 Java.awt。机器人捕捉画面。如果你签署了这个 applet,你的用户将会得到一个“你信任这个应用程序吗”对话框(带有一个“始终信任来自这个发布者的应用程序”复选框) ,然后你就可以使用这个工具了。

然后,您可以使用 LiveConnect 将结果传递给 JavaScript (文档已经过时了,但 Java 小应用程序仍然支持这一点) ,或者您可以将结果发布到服务器上。类似地,您可以从 JavaScript 调用 Javaapplet。

合并在 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.

为了安全起见,你不能用 Javascript 捕获屏幕像素(所以开发人员不能对你的个人数据进行快照) ,但是你可以在 Flash 中做到这一点——你可以使用 Flash. display 在 Flash 容器中获取像素数据。BitmapData 类。

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

使用 Flash 的问题在于它在 iOS 设备上没有得到本地支持,而现在 iOS 设备非常流行,值得开发。闪电侠已经在路上了。

基于画布的方法当然是一个很好的方法,前提是所有访问者都有支持画布标签和 JavaScript 的最新 Web 浏览器。

查看新的输入[ 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 来说) ,那么可以选择一个颜色 从你屏幕上的任何一点开始。还没有跨浏览器,但是干净且基于标准。

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

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

更多详情请参阅白皮书(pdf) : https://www.contextis.com/media/downloads/Pixel_Perfect_Timing_Attacks_with_HTML5_Whitepaper.pdf

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

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

因此,为了做到这一点,我们必须使用类似于 HTML2CanvasDOM 熊猫的东西来获取我们的网站的“截图”,得到用户的点击位置,并得到在特定位置的“截图”的像素颜色。

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

演示

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();
})

如果您不理解异步/等待良好:

const eyeDropper = new EyeDropper()


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

我太喜欢这个功能了

我知道这是一个非常老的帖子,但一个新的 API 调用功能来自谷歌 chrome 被称为“ eyDropper”

这是那个博客上的

const eyeDropper = new EyeDropper();


try {
const selectedColor = await eyeDropper.open();
console.log(selectedColor);
// logs: { sRGBHex: '#ff0000' }
} catch (err) {
console.log("color selection cancelled");
}
//You can test for support of EyeDropper using the following snippet, if you’re browsing with a browser that supports the EyeDropper API a button will be rendered below the code snippet.


if ("EyeDropper" in window) {
// supported
}

Https://pqina.nl/blog/use-the-javascript-eye-dropper-api-to-select-colors-on-the-web/

关于@BorrisTB 的回答,我想补充两点重要的考虑(以及每个人指出 EyeDropper API 可用性的回答)。

  1. 我们在一个运行顺利的项目上实现了吸管 API 但是我打开了 EyeDropper is undefined 生产服务器。原来它需要 window.isSecureContext = true。这是可能的在本地主机,只在 HTTPS 上。所以使 确保页面是通过 HTTPS 加载的,以便 API 可用。
  2. 目前它只能在基于铬的浏览器和 Mozilla 和 Safari 不支持这个 特性,并且由于安全原因没有支持它的计划。 请参阅下表 Https://developer.mozilla.org/en-us/docs/web/api/eyedropper_api#browser_compatibility