在鼠标移动时从画布获取像素颜色
是否可以获取鼠标下像素点的RGB值?有完整的例子吗?这是我到目前为止所拥有的:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = 'Your URL';
img.onload = function(){
ctx.drawImage(img,0,0);
};
canvas.onmousemove = function(e) {
var mouseX, mouseY;
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
var c = ctx.getImageData(mouseX, mouseY, 1, 1).data;
$('#ttip').css({'left':mouseX+20, 'top':mouseY+20}).html(c[0]+'-'+c[1]+'-'+c[2]);
};
}
Is it possible to get the RGB value pixel under the mouse? Is there a complete example of this? Here's what I have so far:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = 'Your URL';
img.onload = function(){
ctx.drawImage(img,0,0);
};
canvas.onmousemove = function(e) {
var mouseX, mouseY;
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
var c = ctx.getImageData(mouseX, mouseY, 1, 1).data;
$('#ttip').css({'left':mouseX+20, 'top':mouseY+20}).html(c[0]+'-'+c[1]+'-'+c[2]);
};
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这是一个完整的、独立的示例。首先,使用以下 HTML:
然后在画布上放置一些具有随机背景颜色的方块:
并在鼠标悬停时打印每种颜色:
上面的代码假定存在 jQuery 和以下实用程序函数:
在此处查看实际操作:
Here's a complete, self-contained example. First, use the following HTML:
Then put some squares on the canvas with random background colors:
And print each color on mouseover:
The code above assumes the presence of jQuery and the following utility functions:
See it in action here:
如果您需要获取矩形区域的平均颜色,而不是单个像素的颜色,请看一下另一个问题:
If you need to get the average color of a rectangular area, rather than the color of a single pixel, please take a look at this other question:
???? JavaScript - Get average color from a certain area of an image
Anyway, both are done in a very similar way:
???? Getting The Color/Value of A Single Pixel from An Image or Canvas
To get the color of a single pixel, you would first draw that image to a canvas, which you have already done:
And then get the value of a single pixel like this:
???? Speeding Things Up by Getting all ImageData at Once
You need to use this same CanvasRenderingContext2D.getImageData() to get the values of the whole image, which you do by changing its third and fourth params. The signature of that function is:
sx
: The x coordinate of the upper left corner of the rectangle from which the ImageData will be extracted.sy
: The y coordinate of the upper left corner of the rectangle from which the ImageData will be extracted.sw
: The width of the rectangle from which the ImageData will be extracted.sh
: The height of the rectangle from which the ImageData will be extracted.You can see it returns an
ImageData
object, whatever that is. The important part here is that that object has a.data
property which contains all our pixel values.However, note that
.data
property is a 1-dimensionUint8ClampedArray
, which means that all the pixel's components have been flattened, so you are getting something that looks like this:Let's say you have a 2x2 image like this:
Then, you will get them like this:
As calling
getImageData
is a slow operation, you can call it only once to get the data of all the image (sw
= image width,sh
= image height).Then, in the example above, if you want to access the components of the
TRANSPARENT PIXEL
, that is, the one at positionx = 1, y = 1
of this imaginary image, you would find its first indexi
in itsImageData
'sdata
property as:✨ Let's See It in Action
⚠️ Note I'm using a small data URI to avoid
Cross-Origin
issues if I include an external image or an answer that is larger than allowed if I try to use a longer data URI.????️ These colors look weird, don't they?
If you move the cursor around the borders of the asterisk shape, you will see sometimes
avgSolidColor
is red, but the pixel you are sampling looks white. That's because even though theR
component for that pixel might be high, the alpha channel is low, so the color is actually an almost transparent shade of red, butavgSolidColor
ignores that.On the other hand,
avgAlphaColor
looks pink. Well, that's actually not true, it just looks pink because we are now using the alpha channel, which makes it semitransparent and allows us to see the background of the page, which in this case is white.???? Alpha-weighted color
Then, what can we do to fix this? Well, it turns out we just need to use the alpha channel and its inverse as the weights to calculate the components of our new sample, in this case merging it with white, as that's the color we use as background.
That means that if a pixel is
R, G, B, A
, whereA
is in the interval[0, 1]
, we will compute the inverse of the alpha channel,iA
, and the components of the weighted sample as:Note how the more transparent a pixel is (
A
closer to 0), the lighter the color.我知道这是一个老问题,但这是一个替代方案。
我将该图像数据存储在一个数组中,然后在画布上发生鼠标移动事件时:
比每次获取 imageData 容易得多。
I know this is an old question, but here's an alternative.
I'd store that image data in an array, then, on mouse move event over the canvas:
A lot easier than getting the imageData everytime.
我使用 javascript 和 JQuery 合并了 StackOverflow(包括上面的文章)和其他站点中找到的各种参考资料:
这是我的完整解决方案。这里我只使用了画布和一张图像,但是如果您需要在图像上使用
,也是可能的。
Merging various references found here in StackOverflow (including the article above) and in other sites, I did so using javascript and JQuery:
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.每次调用 getImageData 都会减慢进程...为了加快速度,我建议存储图像数据,然后您可以轻松快速地获取像素值,因此执行类似的操作以获得更好的性能
calling getImageData every time will slow the process ... to speed up things i recommend store image data and then you can get pix value easily and quickly, so do something like this for better performance
快速解答
context.getImageData(x, y, 1, 1).data;
返回一个 rgba 数组。例如[50, 50, 50, 255]
这是 @lwburk 的 rgbToHex 函数的一个版本,它将 rgba 数组作为参数。
Quick Answer
context.getImageData(x, y, 1, 1).data;
returns an rgba array. e.g.[50, 50, 50, 255]
Here's a version of @lwburk's rgbToHex function that takes the rgba array as an argument.
我有一个非常简单的从画布获取像素颜色的工作示例。
首先是一些基本的 HTML:
然后是 JS 在画布上绘制一些内容,并获取颜色:
这是一个 工作示例< /a>,看看控制台就可以了。
I have a very simple working example of geting pixel color from canvas.
First some basic HTML:
Then JS to draw something on the Canvas, and to get color:
Here is a working example, just look at the console.
您可以尝试 color-sampler。这是在画布中选取颜色的简单方法。请参阅演示。
You can try color-sampler. It's an easy way to pick color in a canvas. See demo.
@Wayne Burkett 的答案很好。如果您还想提取 alpha 值以获得 rgba 颜色,我们可以这样做:
我将 alpha 值除以 255,因为 ImageData 对象将其存储为 0 - 255 之间的整数,但大多数应用程序(例如,
CanvasRenderingContext2D.fillRect()
) 要求颜色采用有效的 CSS 格式,其中 alpha 值介于 0 和 1 之间。(另请记住,如果提取透明颜色然后将其绘制回来到画布上,它将覆盖之前存在的任何颜色,因此如果您在同一点上绘制颜色
rgba(0,0,0,0.1)
10 次,它将是黑色。)@Wayne Burkett's answer is good. If you wanted to also extract the alpha value to get an rgba color, we could do this:
I divided the alpha value by 255 because the ImageData object stores it as an integer between 0 - 255, but most applications (for example,
CanvasRenderingContext2D.fillRect()
) require colors to be in valid CSS format, where the alpha value is between 0 and 1.(Also remember that if you extract a transparent color and then draw it back onto the canvas, it will overlay whatever color is there previously. So if you drew the color
rgba(0,0,0,0.1)
over the same spot 10 times, it would be black.)