我正在使用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枕头所声称的)。
我猜错了什么
drawImage
做了一些合成(将ctx.globalCompositeOperation
设置为copy
没有任何区别)示例代码
答案 0 :(得分:1)
您的猜测#2是正确的。
浏览器可以通过规范自由地进行Alpha&伽玛对传入图像的调整。
答案 1 :(得分:1)
应用的绘制操作越多,随着时间的推移会出现更多的舍入误差。但是,通过初步抽奖,这无关紧要。
copy
模式不会像您发现的那样影响它。这只是忽略了现有的背景数据。 source-over确实使用了背景的alpha值,但由于最初没有,它会产生相同的效果。
这个问题的主要问题是,由于需要在内部转换预乘的alpha值,因此存在alpha和舍入错误的一般问题。
浏览器确实支持各种级别的色彩管理。这包括PNG文件中的以下数据:
当应用这些数据时,它将改变原始位图。 Gamma不会影响最低值或最高值,但中档会有明显的变化。由于颜色管理和转换错误(1。),仍会更改仍会更改的值。
例如,即使文件没有伽玛块(或#34;文件伽马")(测试文件的情况)或其值为1,显示伽玛仍然会适用(IE中除外)。对于Windows,这将是2.2,对于Mac通常是1.8。
这会在图像返回之前发生,以便在带有画布的代码中使用。
或者,我建议您查看我为此类场景创建的 pngtoy (它的免费/ MIT),以便让开发人员获得原始版本来自PNG的未改变的位图(只看到注释/状态,因为它当前仍处于alpha状态)。我在下面提供了一个代码示例,其中还读取了第三个像素,为预期的红色通道提供了12个。
这将显示原始未更改的位图值。
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;