在JavaScript中读取图像中的像素数据会返回半透明像素的意外结果

在JavaScript中读取图像中的像素数据会返回半透明像素的意外结果,javascript,canvas,Javascript,Canvas,我正在用JavaScript从png文件读取RGBA数据。为此,我在画布上绘制图像并使用.getImageData。数据与我预期的不同: 测试图像: JS中第三个像素的RGBA在chrome和firefox中测试为:[9,0,0,54],但至少应该是[12,0,0,54],这是gimp和python所宣称的 我猜可能有什么不对 drawImage执行一些合成设置ctx.GlobalComposite复制操作没有任何区别 在图像加载时有一些颜色管理正在进行 示例代码 选择测试图像 检查控制台输出

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

测试图像:

JS中第三个像素的RGBA在chrome和firefox中测试为:[9,0,0,54],但至少应该是[12,0,0,54],这是gimp和python所宣称的

我猜可能有什么不对

drawImage执行一些合成设置ctx.GlobalComposite复制操作没有任何区别 在图像加载时有一些颜色管理正在进行 示例代码

选择测试图像 检查控制台输出
你的猜测是正确的

规范允许浏览器自由地对传入图像进行Alpha和Gamma调整。

1合成 应用的绘制操作越多,随着时间的推移,舍入误差将越大。然而,在最初的平局中,这并不重要

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

但主要问题是,由于需要在内部转换的预乘alpha值,alpha和舍入误差存在一般问题

2颜色管理 浏览器支持不同级别的颜色管理。这包括PNG文件中的以下数据:

sRGB块说明PNG如何符合sRGB标准相对、绝对等。 iCCP块,其中包含一个ICC配置文件,包括gamma,如果浏览器支持ICC以及此版本的ICC,则典型版本为版本2和版本4。 如果没有找到sRGB或iCCP配置文件,它将查找包含表示gamma的数字的gamma块。 应用这些数据时,将改变原始位图。Gamma不会影响最低值或最高值,但中等范围会有明显的变化。由于颜色管理和转换错误,仍被更改的值将被更改1

例如,即使文件没有gamma块或文件gamma(测试文件就是这样),或其值为1,显示gamma仍将应用,IE除外。对于windows,这将是2.2,对于Mac,通常是1.8

这发生在图像返回用于canvas代码之前

或者,我建议看一看我为这种类型的场景创建的it's free/MIT,让开发人员能够从PNG获取原始的未更改位图,只需查看注释/状态,因为它目前仍处于alpha状态。我在下面提供了一个代码示例,它还读取了第三个像素,如预期的那样,红色通道为12

使用pngtoy进行试验 这将显示原始的未更改位图值

var out=document.querySelectoroutput, png=新PngToy; 巴布亚新几内亚etchhttps://i.imgur.com/oX1kom7.png.then 函数{png.decode.thenshow} ; 函数showbmp{ var data=bmp.bitmap; out.innerHTML+=数据[8]+,+数据[9]+,+数据[10]+,+数据[11]; }
正在加载IE的外部脚本pngtoy.min.js+Promise polyfill…您有任何证据或来源支持这一点吗?知道怎么解决吗?当然知道。与颜色校正相关的WhatWG规范如下:。这里有一个关于减少浏览器对图像进行颜色校正的问题:。祝你的项目好运!是否可以始终以RGBA格式获取位图数据?而不是rgba/rgb/indexed@FlorianLudwig当然,您可以使用转换器GBBMP,选项。然后。。。bmp从解码。使用选项关闭伽马校正。使用伽马:假。以与画布相同的格式传入位图属性中RGBA缓冲区所在的对象。指向pngtoy的链接已断开。图书馆还有空吗?