我写了一个网站,从图像中提取像素颜色。我是通过在画布上使用getImageData保存图像来做到这一点的。但是,我无法为这个样本图像获得正确的值。
例如,当使用枕头提取第一个像素颜色(x=0,y=0)时,它返回(49,97,172,255)的RGBA颜色空间。
from PIL import Image
im = Image.open('image.png').convert('RGBA')
pix = im.load()
print(pix[0, 0])同样,Java也给出了同样的结果:
BufferedImage bufferedImage = ImageIO.read(new File("image.png"));
int rawRGB = bufferedImage.getRGB(0, 0);
Color color = new Color(rawRGB);然而,当我使用HTML时,我通过getImageData获得以下值:(27,98,178,255)。
let image = new Image();
const reader = new FileReader();
image.addEventListener('load', function () {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext("2d");
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
let data = ctx.getImageData(0, 0, 1, 1).data;
document.getElementById('imageData').innerHTML = data;
});
image.addEventListener('load', function () {
let canvas = document.createElement('canvas');
let gl = canvas.getContext("webgl2");
gl.activeTexture(gl.TEXTURE0);
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this);
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
let data = new Uint8Array(1 * 1 * 4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, data);
document.getElementById('webGl').innerHTML = data;
});
reader.addEventListener('load', (event) => {
image.src = event.target.result;
});
var fileToRead = document.getElementById("yourFile");
fileToRead.addEventListener("change", function (event) {
var files = fileToRead.files;
if (files.length) {
reader.readAsDataURL(event.target.files[0]);
}
}, false);<pre>Expected: 49,97,172,255<br>
ImageData: <span id="imageData"></span><br>
WebGL: <span id="webGl"></span><br></pre>
<input type="file" id="yourFile" name="file">
我不明白为什么会发生这种情况,或者浏览器是如何得出这些值的。我试过Chrome和Firefox,它们显示了相同的错误值。我读过关于预乘阿尔法的文章,但我不知道这如何影响我的结果,因为图片没有使用alpha通道。任何帮助都将不胜感激!
发布于 2021-12-25 15:21:47
这是因为该图像的颜色配置文件被设置为P3,而webGL和2D上下文的默认颜色空间是sRGB,这意味着它们确实转换了图像的颜色。
现在,有一个好消息,Canvas2DAPI最近被扩展到支持P3颜色空间,这可以在最新的Chrome和Safari浏览器中使用(火狐和WebGL很快就会出现)。
要享受这个特性,您需要使用colorSpace: "display-p3"选项创建上下文:
const input = document.querySelector("input");
input.oninput = async(evt) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d", {
colorSpace: "display-p3"
});
if (!(ctx.getContextAttributes?.().colorSpace === "display-p3")) {
console.warn("your browser doesn't support the colorSpace setting");
}
const image = new Image();
image.src = URL.createObjectURL(input.files[0]);
await image.decode();
// not resizing the canvas to save memory since we're only interested in top-left pixel
ctx.drawImage(image, 0, 0);
const { data } = ctx.getImageData(0, 0, 1, 1);
console.log(data);
};<input type="file">
https://stackoverflow.com/questions/70480792
复制相似问题