查找单个 rgb 值是否落在数组中任何 rgb 值的阈值内 - javascript
Finding if a single rgb value falls within a threshold of any rgb value in an array - javascript
对于创建函数以将单个 RGB 值与 RGB 值数组进行比较并确定它是否在阈值范围内的建议,我将不胜感激。这是在原版 javascript 中使用 HTML5 canvas 元素完成的。
我的第一次尝试:
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15; //the threshold
//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data
for(var row = 0; row < canvas.height; row++){ //stepping through the pixels
for (var col = 0, index = 0, colorTotal = 0; col < canvas.width; col++){
index = (col + (row * canvas.width)) * 4;
colorTotal = pixelData.data[index] + pixelData.data[index + 1] + pixelData.data[index + 2]; //add the rgb values of the current pixel
for(var i = 0, pixelColorTotal = 0, result = 0; i < colorArray.length; i++){ //stepping through the colorArray
pixelColorTotal = colorArray[i] [0] + colorArray[i] [1] + colorArray[i] [2]; //add the rgb values of the current array element
result = Math.abs(colorTotal - pixelColorTotal); //find the difference between the color totals
if(result < threshold){
//..do something we've breached the threshold
}
}
}
}
这不是很好,因为例如:[255, 0, 50] 和 [50, 255, 0] 甚至不接近相同的颜色,但它们会触发阈值。
我的第二次尝试:
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15; //the threshold
//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data
for(var row = 0; row < canvas.height; row++){ //stepping through the pixels
for (var col = 0, index = 0; col < canvas.width; col++){
index = (col + (row * canvas.width)) * 4;
for(var i = 0, result = 0; i < colorArray.length; i++){ //stepping through the colorArray
result = Math.abs(pixelData.data[index] - colorArray[i] [0]); //load red difference
if(result >= threshold){ //check the red channel to see if it exceeds threshold
result = Math.abs(pixelData.data[index + 1] - colorArray[i] [1]); //load green difference
if(result >= threshold){ //check the green channel to see if it exceeds threshold
result = Math.abs(pixelData.data[index + 2] - colorArray[i] [2]); //load blue difference
if(result >= threshold){ //check the green channel to see if it exceeds threshold
//do something we have passed all the threshold checks
}
}
}
}
}
}
这样更好,但效率很低。
有没有更好的主意?感谢阅读。
我不是 100% 确定你想要什么,所以如果我走错了方向,请告诉我。
function withinThreshold(colorArr, inputArr, threshold){
let maxThreshold = threshold;
let minThreshold = threshold * -1;
for(var i = 0; i < colorArr.length; i++){
let rDiff = colorArr[i][0] - inputArr[0];
let gDiff = colorArr[i][1] - inputArr[1];
let bDiff = colorArr[i][2] - inputArr[2];
if(rDiff > minThreshold && rDiff < maxThreshold &&
gDiff > minThreshold && gDiff < maxThreshold &&
bDiff > minThreshold && gDiff < maxThreshold){
return i
}
}
return -1
}
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15;
for(var row = 0; row < canvas.height; row++){
for (var col = 0; col < canvas.width; col++){
let pixel = ctx.getImageData(row, col, 1, 1);
let match = withinThreshold(colorArray, pixel, threshold);
if(match === -1){
console.log('no match found');
}else{
console.log('match found! index:',match);
}
// I made it like indexOf, it will return the matching index of colorArr.
// You can simplify it like this:
/*
if(match > -1){
console.log('match found');
}
*/
}
}
另外不要忘记 getImageData 很可能会 return 4 位数组 [r,g,b,a],除非您将设置更改为不允许 alpha。
我也做了它,所以它单独抓取它需要的像素数据。这样,将来您可以将其细化到特定位置,而无需检查所有内容。只需将 row 和 canvas.width 更改为 10 和 20。这样您就可以只保存更改区域的处理。您也可以使用 col 和 canvas.height 来缩小它。
我制作了一些 canvas 渲染引擎,所以我 运行 遇到了性能问题并且不得不处理大量优化。
对于创建函数以将单个 RGB 值与 RGB 值数组进行比较并确定它是否在阈值范围内的建议,我将不胜感激。这是在原版 javascript 中使用 HTML5 canvas 元素完成的。
我的第一次尝试:
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15; //the threshold
//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data
for(var row = 0; row < canvas.height; row++){ //stepping through the pixels
for (var col = 0, index = 0, colorTotal = 0; col < canvas.width; col++){
index = (col + (row * canvas.width)) * 4;
colorTotal = pixelData.data[index] + pixelData.data[index + 1] + pixelData.data[index + 2]; //add the rgb values of the current pixel
for(var i = 0, pixelColorTotal = 0, result = 0; i < colorArray.length; i++){ //stepping through the colorArray
pixelColorTotal = colorArray[i] [0] + colorArray[i] [1] + colorArray[i] [2]; //add the rgb values of the current array element
result = Math.abs(colorTotal - pixelColorTotal); //find the difference between the color totals
if(result < threshold){
//..do something we've breached the threshold
}
}
}
}
这不是很好,因为例如:[255, 0, 50] 和 [50, 255, 0] 甚至不接近相同的颜色,但它们会触发阈值。
我的第二次尝试:
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15; //the threshold
//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data
for(var row = 0; row < canvas.height; row++){ //stepping through the pixels
for (var col = 0, index = 0; col < canvas.width; col++){
index = (col + (row * canvas.width)) * 4;
for(var i = 0, result = 0; i < colorArray.length; i++){ //stepping through the colorArray
result = Math.abs(pixelData.data[index] - colorArray[i] [0]); //load red difference
if(result >= threshold){ //check the red channel to see if it exceeds threshold
result = Math.abs(pixelData.data[index + 1] - colorArray[i] [1]); //load green difference
if(result >= threshold){ //check the green channel to see if it exceeds threshold
result = Math.abs(pixelData.data[index + 2] - colorArray[i] [2]); //load blue difference
if(result >= threshold){ //check the green channel to see if it exceeds threshold
//do something we have passed all the threshold checks
}
}
}
}
}
}
这样更好,但效率很低。
有没有更好的主意?感谢阅读。
我不是 100% 确定你想要什么,所以如果我走错了方向,请告诉我。
function withinThreshold(colorArr, inputArr, threshold){
let maxThreshold = threshold;
let minThreshold = threshold * -1;
for(var i = 0; i < colorArr.length; i++){
let rDiff = colorArr[i][0] - inputArr[0];
let gDiff = colorArr[i][1] - inputArr[1];
let bDiff = colorArr[i][2] - inputArr[2];
if(rDiff > minThreshold && rDiff < maxThreshold &&
gDiff > minThreshold && gDiff < maxThreshold &&
bDiff > minThreshold && gDiff < maxThreshold){
return i
}
}
return -1
}
var colorArray = [ //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];
var threshold = 15;
for(var row = 0; row < canvas.height; row++){
for (var col = 0; col < canvas.width; col++){
let pixel = ctx.getImageData(row, col, 1, 1);
let match = withinThreshold(colorArray, pixel, threshold);
if(match === -1){
console.log('no match found');
}else{
console.log('match found! index:',match);
}
// I made it like indexOf, it will return the matching index of colorArr.
// You can simplify it like this:
/*
if(match > -1){
console.log('match found');
}
*/
}
}
另外不要忘记 getImageData 很可能会 return 4 位数组 [r,g,b,a],除非您将设置更改为不允许 alpha。
我也做了它,所以它单独抓取它需要的像素数据。这样,将来您可以将其细化到特定位置,而无需检查所有内容。只需将 row 和 canvas.width 更改为 10 和 20。这样您就可以只保存更改区域的处理。您也可以使用 col 和 canvas.height 来缩小它。
我制作了一些 canvas 渲染引擎,所以我 运行 遇到了性能问题并且不得不处理大量优化。