【问题标题】:HTML Canvas inaccurately sets pixel color when alpha is lower than one当 alpha 小于 1 时,HTML Canvas 不准确地设置像素颜色
【发布时间】:2017-02-17 17:49:08
【问题描述】:

请看这个例子:http://codepen.io/anon/pen/QNGzBP

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

// set pixel at 0,0 to rgba(2, 0, 255, 0.2)
const imageData = ctx.getImageData(0, 0, 1, 1)
imageData.data[0] = 2
imageData.data[1] = 0
imageData.data[2] = 255
imageData.data[3] = 0.2 * 255 // 0.2 opacity
ctx.putImageData(imageData, 0, 0, 0, 0, 1, 1)
console.log('Setting pixel 0,0 to', {
  r: imageData.data[0],
  g: imageData.data[1],
  b: imageData.data[2],
  a: imageData.data[3] / 255
})

// retrieve pixel at 0,0
const newImageData = ctx.getImageData(0, 0, 1, 1)
console.log('Fetching pixel at 0,0', {
  r: newImageData.data[0],
  g: newImageData.data[1],
  b: newImageData.data[2],
  a: newImageData.data[3] / 255
})

上面的代码修改了画布上的单个像素,然后检索它,同时控制台记录该过程。当 alpha 低于 1 时,画布似乎会改变 RGB 数据。

它似乎同时出现在 Chrome 和 Firefox 中。这仅仅是一个浏览器错误吗?我正在用画布制作 PNG,并要求颜色 100% 准确。有什么解决办法吗?

编辑:

http://codepen.io/anon/pen/ZWLbKx

更多测试显示 alpha 如何改变 rgb 值。

【问题讨论】:

  • canvas imageData的alpha元素为0-255范围内的整数。非整数无效(它们可能会被装箱或忽略)。
  • 是的,但它仍然会改变值,即使您将a 设置为51,至少对我来说是这样。ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")"; ctx.fillRect( x, y, 1, 1 ); 按预期工作,并且能够稍后成功取回值
  • 我做了第二次测试,更好地表明 rgb 被 alpha 突变了。
  • @Wish fillRect 似乎也不起作用:codepen.io/anon/pen/mPRVRw 想看看你是如何做到的?
  • 是的,你是对的,它还在变异..

标签: javascript html canvas


【解决方案1】:

很抱歉让您失望,但 HTML5 画布已被批准为“有损”:它使用 alpha 通道预乘法。

来自https://www.w3.org/TR/2dcontext/#dom-context-2d-getimagedata(见第二个“注:”框):

由于与预乘 Alpha 颜色值相互转换的有损特性,刚刚使用 putImageData() 设置的像素可能会作为不同的值返回到等效的 getImageData()

...有很多 JavaScript PNG 编码器/解码器。不幸的是,截至 2017 年,情况就是这样。

FWIW,我尝试上下调整 r/g/b/a 值,以尝试让画布吐出我真正想要的值。 5 分钟的实验表明,它会根据 alpha 设置的值“跳跃”超过您想要的特定像素值。

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 2014-05-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多