【问题标题】:getImageData() does not return correct RGB values (Display P3 image)getImageData() 不返回正确的 RGB 值(显示 P3 图像)
【发布时间】:2022-01-25 13:14:07
【问题描述】:

我编写了一个从图像中提取像素颜色的网站。我通过在包含图像的画布上使用getImageData 来做到这一点。但是,我无法获得 this sample image 的正确值。

例如,当使用 Pillow 提取第一个像素颜色 (x=0, y=0) 时,它会为 RGBA 颜色空间返回 (49, 97, 172, 255)。

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,它们显示的值相同。我已经读过premultiplied alphas,但我不知道这会如何影响我的结果,因为图片没有使用 alpha 通道。任何帮助将不胜感激!

【问题讨论】:

  • 这很可能是由于浏览器中的缩放。你的图片是 6016x6016,画布可能更小,所以浏览器需要缩放,随着像素的移动,一些像素会完全消失。
  • 您是否介意我们使用 stackoverflow 的 imgur 帐户存储您的图像,以便将来的读者也可以访问它,即使您将其从 GDrive 中删除?
  • @Kaiido 请继续这样做。我只是不知道该怎么做,因为图像很大
  • 哦,你说得对,它对 imgur 来说太大了,我不得不调整图像大小,然后他们将其转换为 JPEG(幸运的是保留了颜色配置文件),所以我更改了值。

标签: javascript html image canvas html5-canvas


【解决方案1】:

这是因为此图像的颜色配置文件设置为 P3,而 webGL 和 2D 上下文的默认颜色空间都是 sRGB,这意味着它们会转换您图像的颜色。

现在,有一个好消息,canvas 2D API 最近得到了扩展以支持 P3 颜色空间,这在最新的 Chrome 和 Safari 浏览器中可用(Firefox 和 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);
};
&lt;input type="file"&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2013-04-25
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多