如何从 img 获取 RGB 数组?
How can I get RGB array from img?
我正在尝试使用 canvas 获取 img 的 RGB 数组,如下所示:
Teplate
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="display"></div>
<img id="face" src="./220px-Leonhard_Euler.jpg" />
<canvas
id="face2"
width="112"
height="112"
style="border: 1px solid #d3d3d3;"
></canvas>
<script src="src/index.js"></script>
</body>
</html>
脚本
const img = document.getElementById("face");
img.crossOrigin = "anonymous";
const canvas = document.getElementById("face2");
const context = canvas.getContext("2d");
context.drawImage(img, 0, 0);
let pix = context.getImageData(0, 0, 112, 112).data;
pix = Array.from(pix);
const pix2 = [];
for (let i = 0; i < pix.length; i += 4) {
pix2.push(pix[i + 0]);
pix2.push(pix[i + 1]);
pix2.push(pix[i + 2]);
}
const imgData = context.createImageData(112, 112);
for (let i = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[i + 0];
imgData.data[i + 1] = pix2[i + 1];
imgData.data[i + 2] = pix2[i + 2];
imgData.data[i + 3] = 255;
}
context.putImageData(imgData, 10, 10);
正如您在代码的第一部分中看到的那样,我尝试提取图像 RGBA 的 4d 数组,并尝试删除 alpha 通道。
在那之后,我尝试使用默认的 alpha 通道(如 255)再次设置图像,只是为了检查我是否只获得了 RGB 数据。
但是我得到了下面的图像:
输入图像是 112x112 而 canvas 是 112x112,知道为什么我只能得到 img 的 RGB 吗?
EDIT2
@tracktor 的响应有效,但我仍然在使用另一张这样的图片时出错:
相同的代码,唯一的区别是我使用 http://localhost:8080/face.jpg 而不是 crossorigin 加载此图像。
谢谢
HTMLImageElement crossorigin
属性
在 HTML 中的 img
标记上放置一个 crossorigin
属性,以确保浏览器 请求 具有 header 的图像s 用于 CORS 操作,例如
Origin: http://localhost
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
在 return 中,用图像数据响应的站点 必须 包括从“来源”请求中设置的“Access-Control-Allow-Origin” header header,比如
Access-Control-Allow-Origin: http://localhost
或通配符版本:
Access-Control-Allow-Origin: *
启用 javascript 访问数据 returned。
注意 https://i.stack.imgur.com
没有 return 访问控制 headers,因此从该域 return 编辑的图像会受到污染canvas objects。如果您正在编写或修改 node/express 服务器以支持 CORS,我强烈建议您阅读 http://expressjs.com/resources/middleware/cors.html。
window load
事件
等到 window load
事件触发后处理图像数据。如果处理较早,图像加载可能不可用。
图像结果损坏
更新post中显示的不正确图像数据是由于pix2
中的rgb数据三元组与[=22=中所需的rgba数据四元组没有对齐造成的].要成功转置像素数据,请尝试等效于:
for (let i = 0, j = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[j++];
imgData.data[i + 1] = pix2[j++];
imgData.data[i + 2] = pix2[j++];
imgData.data[i + 3] = 128; // test value
}
以下代码片段创建了两个 canvas 元素:一个显示加载的图像,另一个显示 canvas 数据操作的结果。该代码在不同端口上使用本地主机服务器,没有它们将无法 运行 成功:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>cross origin</title></head>
<body>
<h2>Image</h2>
<img id="face" crossorigin src="http://localhost:8080/share/imperial.jpg" />
<h2>Canvas</h2>
<canvas
id="face2"
width="112"
height="112"
style="border: 1px solid blue"
></canvas>
<canvas
id="modified"
width="112"
height="112"
style="border: 1px solid red"
></canvas>
<script type="text/javascript">"use strict";
window.addEventListener("load", ()=> {
const img = document.getElementById("face");
const canvas = document.getElementById("face2");
const context = canvas.getContext("2d");
context.drawImage(img, 0, 0);
let imgData1 = context.getImageData(0, 0, 112, 112)
let pix;
try {
pix = imgData1.data;
}
catch( err) {
console.warn( err.message);
}
pix = Array.from(pix);
const pix2 = [];
for (let i = 0; i < pix.length; i += 4) {
pix2.push(pix[i + 0]);
pix2.push(pix[i + 1]);
pix2.push(pix[i + 2]);
}
const imgData = context.createImageData(112, 112);
for (let i = 0, j = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[j++];
imgData.data[i + 1] = pix2[j++];
imgData.data[i + 2] = pix2[j++];
imgData.data[i + 3] = 128; // test value
}
const canvas2 = document.getElementById("modified");
const context2 = canvas2.getContext("2d");
context2.putImageData(imgData, 10, 10);
});
</script></body>
</html>
我正在尝试使用 canvas 获取 img 的 RGB 数组,如下所示:
Teplate
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="display"></div>
<img id="face" src="./220px-Leonhard_Euler.jpg" />
<canvas
id="face2"
width="112"
height="112"
style="border: 1px solid #d3d3d3;"
></canvas>
<script src="src/index.js"></script>
</body>
</html>
脚本
const img = document.getElementById("face");
img.crossOrigin = "anonymous";
const canvas = document.getElementById("face2");
const context = canvas.getContext("2d");
context.drawImage(img, 0, 0);
let pix = context.getImageData(0, 0, 112, 112).data;
pix = Array.from(pix);
const pix2 = [];
for (let i = 0; i < pix.length; i += 4) {
pix2.push(pix[i + 0]);
pix2.push(pix[i + 1]);
pix2.push(pix[i + 2]);
}
const imgData = context.createImageData(112, 112);
for (let i = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[i + 0];
imgData.data[i + 1] = pix2[i + 1];
imgData.data[i + 2] = pix2[i + 2];
imgData.data[i + 3] = 255;
}
context.putImageData(imgData, 10, 10);
正如您在代码的第一部分中看到的那样,我尝试提取图像 RGBA 的 4d 数组,并尝试删除 alpha 通道。
在那之后,我尝试使用默认的 alpha 通道(如 255)再次设置图像,只是为了检查我是否只获得了 RGB 数据。
但是我得到了下面的图像:
输入图像是 112x112 而 canvas 是 112x112,知道为什么我只能得到 img 的 RGB 吗?
EDIT2
@tracktor 的响应有效,但我仍然在使用另一张这样的图片时出错:
相同的代码,唯一的区别是我使用 http://localhost:8080/face.jpg 而不是 crossorigin 加载此图像。
谢谢
HTMLImageElement crossorigin
属性
在 HTML 中的 img
标记上放置一个 crossorigin
属性,以确保浏览器 请求 具有 header 的图像s 用于 CORS 操作,例如
Origin: http://localhost Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site
在 return 中,用图像数据响应的站点 必须 包括从“来源”请求中设置的“Access-Control-Allow-Origin” header header,比如
Access-Control-Allow-Origin: http://localhost
或通配符版本:
Access-Control-Allow-Origin: *
启用 javascript 访问数据 returned。
注意 https://i.stack.imgur.com
没有 return 访问控制 headers,因此从该域 return 编辑的图像会受到污染canvas objects。如果您正在编写或修改 node/express 服务器以支持 CORS,我强烈建议您阅读 http://expressjs.com/resources/middleware/cors.html。
window load
事件
等到 window load
事件触发后处理图像数据。如果处理较早,图像加载可能不可用。
图像结果损坏
更新post中显示的不正确图像数据是由于pix2
中的rgb数据三元组与[=22=中所需的rgba数据四元组没有对齐造成的].要成功转置像素数据,请尝试等效于:
for (let i = 0, j = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[j++];
imgData.data[i + 1] = pix2[j++];
imgData.data[i + 2] = pix2[j++];
imgData.data[i + 3] = 128; // test value
}
以下代码片段创建了两个 canvas 元素:一个显示加载的图像,另一个显示 canvas 数据操作的结果。该代码在不同端口上使用本地主机服务器,没有它们将无法 运行 成功:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>cross origin</title></head>
<body>
<h2>Image</h2>
<img id="face" crossorigin src="http://localhost:8080/share/imperial.jpg" />
<h2>Canvas</h2>
<canvas
id="face2"
width="112"
height="112"
style="border: 1px solid blue"
></canvas>
<canvas
id="modified"
width="112"
height="112"
style="border: 1px solid red"
></canvas>
<script type="text/javascript">"use strict";
window.addEventListener("load", ()=> {
const img = document.getElementById("face");
const canvas = document.getElementById("face2");
const context = canvas.getContext("2d");
context.drawImage(img, 0, 0);
let imgData1 = context.getImageData(0, 0, 112, 112)
let pix;
try {
pix = imgData1.data;
}
catch( err) {
console.warn( err.message);
}
pix = Array.from(pix);
const pix2 = [];
for (let i = 0; i < pix.length; i += 4) {
pix2.push(pix[i + 0]);
pix2.push(pix[i + 1]);
pix2.push(pix[i + 2]);
}
const imgData = context.createImageData(112, 112);
for (let i = 0, j = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = pix2[j++];
imgData.data[i + 1] = pix2[j++];
imgData.data[i + 2] = pix2[j++];
imgData.data[i + 3] = 128; // test value
}
const canvas2 = document.getElementById("modified");
const context2 = canvas2.getContext("2d");
context2.putImageData(imgData, 10, 10);
});
</script></body>
</html>