从JavaScript中的图像读取pixeldata会返回半透明像素的意外结果

时间:2015-03-07 17:05:05

标签: javascript canvas

我正在使用JavaScript从png文件中读取RGBA数据。为此,我在画布上绘制图像并使用.getImageData。数据与我的预期不同:

测试图像: https://raw.githubusercontent.com/FlorianLudwig/imghash/master/test/transparent.png

JS中第三个像素的RGBA是:[9, 0, 0, 54](在chrome和firefox中测试过)但它应该是[12, 0, 0, 54](至少它是gimp和python枕头所声称的)。

我猜错了什么

  1. drawImage做了一些合成(将ctx.globalCompositeOperation设置为copy没有任何区别)
  2. 在图像的加载时间发生了一些色彩错误
  3. 示例代码

    1. http://codepen.io/anon/pen/EaemZw
    2. 选择测试图像
    3. 检查控制台输出

2 个答案:

答案 0 :(得分:1)

您的猜测#2是正确的。

浏览器可以通过规范自由地进行Alpha&伽玛对传入图像的调整。

答案 1 :(得分:1)

1)合成

应用的绘制操作越多,随着时间的推移会出现更多的舍入误差。但是,通过初步抽奖,这无关紧要。

copy模式不会像您发现的那样影响它。这只是忽略了现有的背景数据。 source-over确实使用了背景的alpha值,但由于最初没有,它会产生相同的效果。

这个问题的主要问题是,由于需要在内部转换预乘的alpha值,因此存在alpha和舍入错误的一般问题。

2)色彩管理

浏览器确实支持各种级别的色彩管理。这包括PNG文件中的以下数据:

  • sRGB chunk说明PNG如何符合sRGB标准(相对,绝对等)。
  • iCCP chunk,其中包含一个包含gamma的ICC配置文件,如果浏览器支持ICC以及此版本的ICC(典型版本为版本2和4)。
  • 如果未找到sRGB或iCCP配置文件,它将查找包含代表gamma的数字的gAMA块。

当应用这些数据时,它将改变原始位图。 Gamma不会影响最低值或最高值,但中档会有明显的变化。由于颜色管理和转换错误(1。),仍会更改仍会更改的值。

例如,即使文件没有伽玛块(或#34;文件伽马")(测试文件的情况)或其值为1,显示伽玛仍然会适用(IE中除外)。对于Windows,这将是2.2,对于Mac通常是1.8。

这会在图像返回之前发生,以便在带有画布的代码中使用。

或者,我建议您查看我为此类场景创建的 pngtoy (它的免费/ MIT),以便让开发人员获得原始版本来自PNG的未改变的位图(只看到注释/状态,因为它当前仍处于alpha状态)。我在下面提供了一个代码示例,其中还读取了第三个像素,为预期的红色通道提供了12个。

使用pngtoy进行测试

这将显示原始未更改的位图值。



var out = document.querySelector("output"),
    png = new PngToy();

png.fetch("https://i.imgur.com/oX1kom7.png").then(
  function() {png.decode().then(show)}
);

function show(bmp) {
  var data = bmp.bitmap;
  out.innerHTML += data[8] + "," + data[9] + "," + data[10] + "," + data[11];
}

<script src="https://rawgit.com/epistemex/pngtoy/master/tests/Promise.js"></script>
<script src="https://rawgit.com/epistemex/pngtoy/master/pngtoy.min.js"></script>
<output>Loading external scripts (pngtoy.min.js + Promise polyfill for IE...)<br></output>
&#13;
&#13;
&#13;