- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试查找图像中的所有十六进制颜色,如果可能,圈出或突出显示十六进制颜色所在的 X、Y 位置。我当前的代码正在尝试查找所有颜色,几乎使我的浏览器崩溃,并且我尝试查找每个图像的 X、Y 坐标也进展不顺利。
我有两个函数做不同的事情,这就是我试图用它来给出一个已经尝试过的例子......任何帮助都会很棒!
任何帮助都会很棒!
<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>");
}
}
最佳答案
要找到与颜色匹配的像素,在最坏的情况下(该颜色的像素不在图像中),您需要遍历图像中的每个像素。
将每个像素转换为 DOM 字符串是最糟糕的方法,因为 DOM 字符串使用大量内存和 CPU 开销,尤其是使用 jQuery 实例化时(它有自己的额外包袱)
要查找像素,您只需对照十六进制值检查每个像素的颜色数据。您将十六进制值转换为 3 字节的数组。
以下函数将从 CSS Hex 格式转换 "#HHH"
"#HHHH"
, "#HHHHHH"
和"#HHHHHHHH"
忽略 alpha 部分(如果包含),将其转换为 0-255 的整数数组
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)];
}
我不知道您打算如何使用这样的功能,因此下面的示例是一个通用方法,将有所帮助,并且可以根据需要进行修改
如果你允许的话,即使没有完美的匹配,它总是会找到一个像素。它通过查找与您要查找的颜色最接近的颜色来实现此目的。
找到最接近匹配的原因是,当您将图像绘制到 2D Canvas 上时,如果图像具有透明像素(预乘 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
}
如果图像被污染(跨源、本地设备存储),或者您传递了无法转换为像素的内容,则该函数将返回 undefined
该函数保留一个用于获取像素数据的 Canvas ,因为它假设它将被多次使用。如果图像被污染,它将捕获错误(向控制台添加警告),清理被污染的 Canvas 并为另一个图像做好准备。
要使用该功能,请将其添加到您的代码库中,它将自动设置。
获取图像和十六进制值并使用 image
调用该函数, CSS hex
颜色,以及颜色匹配的阈值距离(可选)。
例如查找 #FF0000 的完全匹配
const result = findPixel(origImage, "#FF0000", 0); // find exact match for red
if (result) { // only if found
console.log("Found color #FF0000 at pixel " + result.x + ", " + result.y);
} else {
console.log("The color #FF0000 is not in the image");
}
或找到接近的颜色
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;
}
})();
此功能已经过测试,并且按上述方式工作。
注意按照问题中的代码,图像的 alpha 值和 CSS 十六进制颜色将被忽略。
请注意,如果您打算从同一图像中查找多种颜色,则此功能并不是最适合您的需求。如果是这种情况,请在评论中告诉我,我可以进行更改或指导您如何乐观地使用代码。
注意它不太适合一次性使用。但是,如果是这种情况,请更改行 const findPixel = (() => {
至var findPixel = (() => {
使用后删除引用 findpixel = undefined;
JS 会清理它所拥有的所有资源。
注意如果您还想获取最接近的找到颜色的实际颜色,那么添加也很简单。在评论中提问。
注意速度相当快(您将很难获得更快的结果),但请注意,对于 4K 及以上的超大图像,可能需要一些时间,并且在非常低端的设备上它可能会导致内存不足错误。如果这是一个问题,那么另一种解决方案是可能的,但速度要慢得多。
关于javascript - 查找图像中的十六进制颜色和 X,Y,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60861356/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!