Javascript 在图像中查找十六进制颜色和X、Y
我试图找到图像中的所有十六进制颜色,如果可能,圈出或突出显示十六进制颜色所在的X、Y位置。我当前的代码试图找到所有颜色,几乎崩溃了我的浏览器,我试图找到每个图像的X,Y坐标也不顺利 我有两个函数做不同的事情,这就是我尝试使用的函数,给出了一个尝试的例子。。。任何帮助都会很好 任何援助都将是惊人的Javascript 在图像中查找十六进制颜色和X、Y,javascript,jquery,css,html5-canvas,Javascript,Jquery,Css,Html5 Canvas,我试图找到图像中的所有十六进制颜色,如果可能,圈出或突出显示十六进制颜色所在的X、Y位置。我当前的代码试图找到所有颜色,几乎崩溃了我的浏览器,我试图找到每个图像的X,Y坐标也不顺利 我有两个函数做不同的事情,这就是我尝试使用的函数,给出了一个尝试的例子。。。任何帮助都会很好 任何援助都将是惊人的 <canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;"> Your brow
<canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<img id="origImage" width="220" height="277" src="loggraph.PNG">
<script>
function getPixel(imgData, index) {
var i = index*4, d = imgData.data;
return [d[i],d[i+1],d[i+2],d[i+3]] // [R,G,B,A]
}
function getPixelXY(imgData, x, y) {
return getPixel(imgData, y*imgData.width+x);
}
function goCheck() {
var cvs = document.createElement('canvas'),
img = document.getElementsByTagName("img")[0];
cvs.width = img.width; cvs.height = img.height;
var ctx = cvs.getContext("2d");
ctx.drawImage(img,0,0,cvs.width,cvs.height);
var idt = ctx.getImageData(0,0,cvs.width,cvs.height);
console.log(getPixel(idt, 852)); // returns array [red, green, blue, alpha]
console.log(getPixelXY(idt,1,1)); // same pixel using x,y
}
function getColors(){
var canvas = document.getElementById("myCanvas");
var devices = canvas.getContext("2d");
var imageData = devices.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
// iterate over all pixels
for(var i = 0, n = data.length; i < n; i += 4) {
var r = data[i];
var g = data[i + 1];
var b = data[i + 2];
var rgb = "("+r+","+g+","+b+")";
var incoming = i*4, d = imageData.data;
var bah = [d[incoming],d[incoming+1],d[incoming+2],d[incoming+3]];
$('#list').append("<li>"+rgb+"</li>");
colorList.push(rgb);
}
$('#list').append("<li>"+[d[incoming],d[incoming+1],d[incoming+2],d[incoming+3]]+"</li>");
}
}
您的浏览器不支持HTML5画布标记。
函数getPixel(imgData,索引){
var i=指数*4,d=imgData.data;
返回[d[i]、d[i+1]、d[i+2]、d[i+3]/[R、G、B、A]
}
函数getPixelXY(imgData,x,y){
返回getPixel(imgData,y*imgData.width+x);
}
函数goCheck(){
var cvs=document.createElement('canvas'),
img=document.getElementsByTagName(“img”)[0];
cvs.width=img.width;cvs.height=img.height;
var ctx=cvs.getContext(“2d”);
ctx.drawImage(img,0,0,cvs.width,cvs.height);
var idt=ctx.getImageData(0,0,cvs.width,cvs.height);
log(getPixel(idt,852));//返回数组[red,green,blue,alpha]
log(getPixelXY(idt,1,1));//使用x,y的相同像素
}
函数getColors(){
var canvas=document.getElementById(“myCanvas”);
var devices=canvas.getContext(“2d”);
var imageData=devices.getImageData(0,0,canvas.width,canvas.height);
var数据=imageData.data;
//迭代所有像素
对于(变量i=0,n=data.length;i”+rgb+””;
颜色列表推送(rgb);
}
$(“#列表”)。追加(“”+[d[incoming],d[incoming+1],d[incoming+2],d[incoming+3]+” ”;
}
}
必须检查所有像素
要找到与颜色匹配的像素,在最坏的情况下(该颜色的像素不在图像中),需要跨过图像中的每个像素
怎么不做呢
将每个像素转换为DOM字符串大概是最糟糕的方法,因为DOM字符串会占用大量内存和CPU开销,尤其是使用jQuery实例化时(它有自己的额外负担)
十六进制颜色到数组
要找到像素,只需对照十六进制值检查每个像素的颜色数据。将十六进制值转换为3个字节的数组
以下函数将从CSS十六进制格式“#HHH”
“#HHH”,“#HHHHHH”
和“#hhhhhhhhh”
转换为一个整数数组(如果包括alpha部分)
const hex2RGB = h => {
if(h.length === 4 || h.length === 5) {
return [parseInt(h[1] + h[1], 16), parseInt(h[2] + h[2], 16), parseInt(h[3] + h[3], 16)];
}
return [parseInt(h[1] + h[2], 16), parseInt(h[3] + h[4], 16), parseInt(h[5] + h[6], 16)];
}
寻找像素
我不知道您打算如何使用这样的功能,因此下面的示例是一个通用方法,可以根据需要进行修改
即使没有完美的匹配,如果你允许,它也会找到一个像素。它通过查找最接近您要查找的颜色来实现这一点
of找到最接近匹配的原因是,当您在2D画布上绘制图像时,如果图像具有透明像素(预乘alpha),则像素值会稍微修改
该函数通过测量像素和十六进制颜色(简单几何毕达哥拉斯)之间的空间距离来查找像素。最接近的颜色是距离最小的颜色
它将返回对象
{
x, // the x coordinate of the match
y, // the y coordinate of the match
distance, // how closely the color matches the requested color.
// 0 means a perfect match
// to 441 completely different eg black and white
// value is floored to an integer value
}
如果图像受到污染(跨原点、本地设备存储),或者您传递了无法转换为像素的内容,则函数将返回未定义的
该函数保留一个画布,用于获取像素数据,因为它假设将多次使用该画布。如果图像受到污染,它将捕获错误(向控制台添加警告),清理受污染的画布并准备好处理另一个图像
用法
若要使用此功能,请将其添加到代码库中,它将自动设置
获取图像和十六进制值,并使用图像
、CSS十六进制
颜色以及颜色匹配的阈值距离调用函数
例如找到#FF0000的精确匹配项
或者找到接近的颜色
const result = findPixel(origImage, "#FF0000", 20); // find a match for red
// within 20 units.
// A unit is 1 of 256
if (result) { // only if found
console.log("Found closest color within " + result.distance + "units of #FF0000 at pixel " + result.x + ", " + result.y);
}
或者找到最近的
// find the closest, no threshold ensures a result
const result = findPixel(origImage, "#FF0000");
console.log("Found closest color within " + result.distance + "units of #FF0000 at pixel " + result.x + ", " + result.y);
代码
功能如下
const findPixel = (() => {
var can, ctx;
function createCanvas(w, h) {
if (can === undefined){
can = document.createElement("canvas");
ctx = can.getContext("2d");
}
can.width = w;
can.height = h;
}
function getPixels(img) {
const w = img.naturalWidth || img.width, h = img.naturalHeight || img.height;
createCanvas(w, h);
ctx.drawImage(img, 0, 0);
try {
const imgData = ctx.getImageData(0, 0, w, h);
can.width = can.height = 1; // make canvas as small as possible so it wont
// hold memory. Leave in place to avoid instantiation overheads
return imgData;
} catch(e) {
console.warn("Image is un-trusted and pixel access is blocked");
ctx = can = undefined; // canvas and context can no longer be used so dump them
}
return {width: 0, height: 0, data: []}; // return empty pixel data
}
const hex2RGB = h => { // Hex color to array of 3 values
if(h.length === 4 || h.length === 5) {
return [parseInt(h[1] + h[1], 16), parseInt(h[2] + h[2], 16), parseInt(h[3] + h[3], 16)];
}
return [parseInt(h[1] + h[2], 16), parseInt(h[3] + h[4], 16), parseInt(h[5] + h[6], 16)];
}
const idx2Coord = (idx, w) => ({x: idx % w, y: idx / w | 0});
return function (img, hex, minDist = Infinity) {
const [r, g, b] = hex2RGB(hex);
const {width, height, data} = getPixels(img);
var idx = 0, found;
while (idx < data.length) {
const R = data[idx] - r;
const G = data[idx + 1] - g;
const B = data[idx + 2] - b;
const d = R * R + G * G + B * B;
if (d === 0) { // found exact match
return {...idx2Coord(idx / 4, width), distance: 0};
}
if (d < minDist) {
minDist = d;
found = idx;
}
idx += 4;
}
return found ? {...idx2Coord(found / 4, width), distance: minDist ** 0.5 | 0 } : undefined;
}
})();
constfindpix=(()=>{
var-can,ctx;
函数createCanvas(w,h){
如果(can==未定义){
can=document.createElement(“画布”);
ctx=can.getContext(“2d”);
}
can.width=w;
can.height=h;
}
函数getPixels(img){
常数w=img.naturalWidth | | img.width,h=img.naturalHeight | | img.height;
createCanvas(w,h);
ctx.drawImage(img,0,0);
试一试{
常量imgData=ctx.getImageData(0,0,w,h);
can.width=can.height=1;//使画布尽可能小,这样它就不会
//保留内存。保留内存以避免实例化开销
返回imgData;
}第(e)款{
console.warn(“图像不可信,像素访问被阻止”);
ctx=can=undefined;//画布和上下文不能再使用,因此转储它们
}
返回{宽度:0,高度:0,数据:[]};//返回空像素数据
}
const hex2RGB=h=>{//Hex color到3个值的数组
如果(h.length==4 | | h.length==5){
返回[parseInt(h[1]+h[1],16),parseInt(h[2]+h[2],16),parseInt(h[3]+h[3],16)];
}
return[parseInt(h[1]+h[2],16),parseInt(h[3
const findPixel = (() => {
var can, ctx;
function createCanvas(w, h) {
if (can === undefined){
can = document.createElement("canvas");
ctx = can.getContext("2d");
}
can.width = w;
can.height = h;
}
function getPixels(img) {
const w = img.naturalWidth || img.width, h = img.naturalHeight || img.height;
createCanvas(w, h);
ctx.drawImage(img, 0, 0);
try {
const imgData = ctx.getImageData(0, 0, w, h);
can.width = can.height = 1; // make canvas as small as possible so it wont
// hold memory. Leave in place to avoid instantiation overheads
return imgData;
} catch(e) {
console.warn("Image is un-trusted and pixel access is blocked");
ctx = can = undefined; // canvas and context can no longer be used so dump them
}
return {width: 0, height: 0, data: []}; // return empty pixel data
}
const hex2RGB = h => { // Hex color to array of 3 values
if(h.length === 4 || h.length === 5) {
return [parseInt(h[1] + h[1], 16), parseInt(h[2] + h[2], 16), parseInt(h[3] + h[3], 16)];
}
return [parseInt(h[1] + h[2], 16), parseInt(h[3] + h[4], 16), parseInt(h[5] + h[6], 16)];
}
const idx2Coord = (idx, w) => ({x: idx % w, y: idx / w | 0});
return function (img, hex, minDist = Infinity) {
const [r, g, b] = hex2RGB(hex);
const {width, height, data} = getPixels(img);
var idx = 0, found;
while (idx < data.length) {
const R = data[idx] - r;
const G = data[idx + 1] - g;
const B = data[idx + 2] - b;
const d = R * R + G * G + B * B;
if (d === 0) { // found exact match
return {...idx2Coord(idx / 4, width), distance: 0};
}
if (d < minDist) {
minDist = d;
found = idx;
}
idx += 4;
}
return found ? {...idx2Coord(found / 4, width), distance: minDist ** 0.5 | 0 } : undefined;
}
})();