【问题标题】:HTML canvas returns "off-by-some" bytes from getImageDataHTML 画布从 getImageData 返回“off-by-some”字节
【发布时间】:2020-02-05 21:02:12
【问题描述】:

我发现 HTML 画布的 getImageData 似乎返回了不正确的字节值。

我使用以下 Python 代码生成了一个 1x1 像素的图像:

from PIL import Image
import numpy as np

a = np.array([[[12, 187, 146, 62]]], dtype=np.uint8)
Image.fromarray(a).save('image.png')

我将图像转换为 base64 以将其包含在此代码 sn-p 中:

let image = document.createElement('img');
image.addEventListener('load', () => {
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext("2d");
  canvas.width = image.width;
  canvas.height = image.height;
  ctx.drawImage(image, 0, 0);
  let data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
  document.body.innerHTML = data;
});

image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGPg2T3JDgADyAGYmiSbAQAAAABJRU5ErkJggg==";

在 Firefox 中运行时,它显示12,189,148,62。在 Chromium 中,它显示 12,185,144,62。但原始值为12,187,146,62

谁能解释一下?

【问题讨论】:

  • 声明:使用WebGL可以读取图像的准确字节值。

标签: javascript html5-canvas


【解决方案1】:

Firefox 预乘舍入错误

我可以确认 FF (Firefox) 确实将像素值返回为[12,189,148,62]

当渲染到画布时,像素根据globalCompositeOperation 的值进行处理,默认为"source-over"。计算是在 FF 接缝不正确舍入的预乘 alpha 值上执行的。

注意关闭CanvasRenderingContext2D的alpha canvas.getContext("2d", {alpha: false}),得到的像素是FF [3,46,36,255]和Chrome [3,45,35,255]

Chrome 具有正确的值,如下面的 sn-p 所示。

// correct pre mult alpha 
console.log([12,187,146].map(c => Math.round(c * 62 / 255)) + "");

FF 出于某种原因正在四舍五入,我认为这是一个 错误

alpha: true 导致高于预期值时,此舍入误差(在 FF 中)会影响 "source-over" 合成的结果。

有关合成W3C Compositing and Blending的更多信息

修复?

我不能提出修复建议,只能说 Chrome 正在正确渲染图像,而 FF 不是。

【讨论】:

猜你喜欢
  • 2016-04-29
  • 2021-05-20
  • 1970-01-01
  • 2017-12-15
  • 2013-12-04
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多