The Way To Great

Premultiplied Alpha的秘密

我得承认题目有点标题党的意思,自从Flash播放器采用了BitmapData以来,Flash采用一种叫做Premultipled Alpha的技术来存储透明的像素。但是它还是有点…为了避免你觉得我啰里巴索你可以直接去检查示例程序, check out the demo right away 如果没看懂,呵呵……

"Premultiplied" alpha技术意味着不仅像素的Alpha信息存储在通道里,而且已经扩张到红,蓝,绿通道里,在实际应用中这意味着如果你保存着 #fff8000橙色,而将其透明度设置为50%,那么实际设置保存的是#80803f00.这意味着颜色通道中的任意像素值都不会比Alpha通道中的值来的大

这样做的原因是出于性能的考虑,图像处理算法在复合两张图片的时候总是需要将ALPHA通道的信息复合到各个颜色通道,因此如果你需要处理很多的图像复合时候,这样的做法就节省了很多的时间,而不需要对每个像素重新进行复合,正如我们所知道的Flash的日常处理中有很多时候都在处理复合,比如重合两张反锯齿的直线时就会有复合,有了这样的处理之后Flash的速度就很快了。

但是也有一个问题,像素是以32位的整数值存储的,也就是说每个通道有8位或者256种可能的值,另一方面像素的计算通常是以浮点数学的方式进行的,也就是说可能的值要远大的多,如果通常以浮点处理那很好,但是有些情况下你不得不将浮点的值回写到像素信息,也就是说比如43.7回写的时候就会圆整为44或者更糟的43回写到像素值里面

通常情况下这种小的误差不会对应用造成很大的麻烦,但是一旦你开始处理小的像素值,那么错误就会被基类放大,,例如如果你将一个像素的ALPHA值设置为16那么每一个像素都会被乘上一个因子16/256=0.0625,因此灰色像素就会变成128*0.0625=8 暗像素64就会变成4,但是稍微亮一点的像素如67也会变成4,注意没有小数这是圆整后的结果,你会发现颜色种类减少了,从原来的256×256×256减少到8*8*8,严重的问题

如果你将ALPHA值保持设置为8那么不会有太大的问题,如果你增大ALPHA值,那么灾难就出现了,,大量的颜色信息由于进度原因会丢失,而且无法修复。

为了解释清楚到底是怎么回事我设置了一个Demo demo that visualizes the amount of information loss来解释。它先将图像的Alpha通道设置为一个选定值,然后再设置回255,你所观察到的现象正好说明了,当Alpha值很小的时候会有些海报斑驳效果,即使你将像素设置为254,你也会发现颜色丢失的现象(复选 观察数据丢失复选框)该复选框会对比颜色丢失和未丢失的情况,由于有的时候丢失不是很明显,DEMO将该丢失放大了以增强了对比度

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="PremultipliedAlphaLossDemo" width="560" height="486" codebase=""> <param name="movie" value="PremultipliedAlphaLossDemo.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#869ca7" /> <param name="allowScriptAccess" value="sameDomain" /> <embed src="PremultipliedAlphaLossDemo.swf" quality="high" bgcolor="#869ca7"width="560" height="486" name="PremultipliedAlphaLossDemo" align="middle"play="true"loop="false"quality="high"allowScriptAccess="sameDomain"type="application/x-shockwave-flash"pluginspage=""> </embed> </object>

那要怎样才能保存颜色信息呢,你只有慢慢来,效率和质量不可兼得么,将Alpha信息和像素分开存储,也就是说你维护着三张Bitmap一张存储颜色信息,一张存储Alpha值,第三章存储两者复合后的结果。

The Dirty Secrets of Premultiplied Alpha

Okay, I’m exaggerating. Several years after BitmapData was introduced to the Flash player it’s not really a secret anymore that Flash uses a feature called premultiplied alpha when it stores transparent pixels. But it is a bit dirty after all. In case you want to skip the following nerd talk you can check out the demo right away – but don’t cry if you don’t understand what it is telling you.

"Premultiplied" alpha means that the alpha information of a pixel is not only stored in the alpha channel itself, but it is already "multiplied" into the red, green and blue channel. In Flash practice this means that if you have a nice orange #fff8000 and reduce the alpha to 50% it will be stored as #80803f00. This means that each value of the color channels will never be bigger than that of the alpha channel.

The reason to do this is performance. The image processing algorithm to composite two bitmaps always requires that the alpha channels are being multplied into the color information, so if you have a tool that needs to do a lot of compositing it simply saves you a good amount of time if you don’t have to do these multiplications for every pixel. And as we know Flash is all about compositing things (whenever you overlap two antialiased lines some serious composting takes place) and Flash is pretty fast with this.

But there is a problem. Pixels are stored as 32 bit integer values, this means each channel has a range of 8 bit or 256 possible values. On the other hand calculations with pixels usually are done in floating point mathematics which means that the range of possible in-between values can be much higher. As long as you stay within floating point that’s cool, but unfortunatly at some point you have to write those values back into a bitmap which means that if you have a result of 43.7 it will be rounded to 44 or even worse to 43.

对的,坚持;错的,放弃!

The Way To Great

相关文章:

你感兴趣的文章:

标签云: