从 JavaScript 中的图像中读取像素数据会返回半透明像素的意外结果
Reading pixeldata from images in JavaScript returns unexpected results for semi transparent pixels
我正在从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
没有任何区别) - 加载图像时正在进行一些颜色管理
示例代码
- http://codepen.io/anon/pen/EaemZw
- 选择测试图像
- 检查控制台输出
1) 合成
应用的绘制操作越多,随着时间的推移,舍入误差就越多。但是,对于初始抽奖,这并不重要。
copy
模式不会影响您发现的它。这只是忽略现有的后台数据。源结束确实使用背景的 alpha 值,但由于最初没有,因此将具有相同的效果。
不过,这样做的主要问题是,由于需要在内部转换的预乘 alpha 值,存在 alpha 和舍入误差的普遍问题。
2) 色彩管理
浏览器确实支持各种级别的颜色管理。这包括 PNG 文件中的以下数据:
- sRGB 块,说明 PNG 如何符合 sRGB 标准(相对、绝对等)
- iCCP 块,其中包含包含 gamma 的 ICC 配置文件,如果浏览器支持 ICC 以及此版本的 ICC(典型版本是版本 2 和 4)。
- 如果未找到 sRGB 或 iCCP 配置文件,它将查找包含表示 gamma 的数字的 gAMA 块。
应用这些数据时,它将更改原始位图。Gamma 不会影响最低值或最高值,但中间值会有明显的变化。由于颜色管理和转换错误 (1.),仍更改的值将更改。
例如,即使文件没有 gamma 块(或"文件 gamma"),测试文件就是这种情况,或者其值为 1,仍将应用显示 gamma(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>
你的猜测#2是正确的。
规范赋予浏览器自由,可以对传入的图像进行 Alpha 和 Gamma 调整。
- 如何通过溢出来判断元素被切断了多少像素:隐藏在父级上
- 点击facebook像素跟踪注册(JS/JQUERY代码)
- 点击(右键点击)使用传单地图库获取图像覆盖的像素坐标
- 如何使线条的边缘像素保持半透明
- 画布:逐像素绘制图像并请求动画帧计时
- 如何's css标记"-webkit最小设备像素比”;在Javascript中实现
- javascript mootools平滑滚动'x'像素数量
- 逐像素碰撞检测弹球
- 从 JavaScript 中的图像中读取像素数据会返回半透明像素的意外结果
- jQuery .css() 返回像素而不是百分比
- .height() 以百分比返回高度,如何以像素为单位获取它
- 获取返回的数据表的大小(以像素为单位)
- canvas getImageData 返回太多像素
- 在IE9中,getComputedStyle总是返回像素值
- jQuery .css返回以像素为单位的 css 属性,而实际上以百分比为单位
- 为什么getComputedStyle返回'auto'用于元素创建后的像素值
- 从WebGL 3D画布读取像素信息,返回所有[0,0,0,255]
- jQuery.width()返回百分比宽度而不是像素宽度
- 返回画布对象的像素
- javascript getImageData未从png图像返回正确的像素颜色