Phr*_*ogz 19 javascript html5 canvas
当使用putImageData我将像素写入HTML Canvas上下文时,我发现当我再次获取它们时,像素值并不完全相同.我已经提出了一个显示问题的示例测试页面.归结起来,问题是:
var id = someContext.getImageData(0,0,1,1);
id.data[0]=id.data[3]=64; // 25% red, 25% alpha
id.data[1]=id.data[2]=0; // No blue or green
someContext.putImageData(id,0,0);
var newData = someContext.getImageData(0,0,1,1);
console.log( newData.data[0] );
Run Code Online (Sandbox Code Playgroud)
在Chrome v8上,红色值返回为63; 在Firefox v3.6,Safari v5和IE9上,红色值返回67(全部在Windows上).在OS X上,Chrome v7,Safari v5和Firefox v3.6也会重新出现67.它们都没有像64最初设定的那样回来!
使用setTimeout设置和重新获取之间的延迟没有任何区别.更改页面的背景没有任何区别.使用save()和restore()在上下文(根据这个不太可能的文章)没有任何区别.
oll*_*iej 15
ImageData在HTML5中定义为未经过多次映射,但大多数画布实现使用预乘的后备缓冲区来加速合成等.这意味着当写入数据然后从后备缓冲区读取数据时,它可以更改.
我认为Chrome v8从webkit.org中获取了一个错误版本的[un]预乘代码(它之前已被打破过,虽然我不记得最近出现的任何情况,但这并不能解释windows只有变化)
[编辑:可能值得在Windows上每晚查看一个webkit吗?因为imagedata实现没有任何特定于平台的,所以它在所有webkit浏览器之间共享,并且可以简单地在基于MSVC的构建中被破坏]
HTML5规范鼓励浏览器供应商使用称为的东西Premultiplied Alpha。从本质上讲,这意味着像素以32位整数存储,其中每个通道包含一个8位颜色值。出于性能原因,浏览器使用预乘Alpha。这意味着它会根据alpha值预乘颜色值。
这是一个例子。你有一个颜色,对于RGB值是128,64,67。现在,为了获得更高的性能,颜色值将预乘以Alpha值。因此,如果alpha值为16,则所有颜色值都将乘以16/256(= 0.0625)。在这种情况下,对于RGB所得值成为8,4,4.1875(四舍五入至4因为像素颜色值不漂浮)。
当您完全按照此处的操作进行操作时,就会出现问题。使用特定的Alpha值设置颜色数据,然后拉回实际的颜色值。4.1875四舍五入到的以前的蓝色4将变为,64而不是67在您调用时getImageData()。
这就是为什么您看到所有这些的原因,除非浏览器引擎中的基础实现更改为使用不受此影响的彩色系统,否则它永远不会改变。