`

透明像素-Premultiplied Alpha的秘密

    博客分类:
  • ios
 
阅读更多

转载:http://blog.csdn.net/zinking3/article/details/2260405

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将该丢失放大了以增强了对比度

 

那要怎样才能保存颜色信息呢,你只有慢慢来,效率和质量不可兼得么,将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.

Normally these little errors do not cause much trouble. But once you start dealing with small alpha values the error accumulates. An example: when you set the alpha value of a pixel to 16 all color values will be multiplied with a factor of 16/256 = 0.0625. So a gray pixel of 128 will become 128 * 0.0625 = 8, a darker pixel of 64 will become 64 * 0.0625 = 4. But a slightly lighter pixel of maybe 67 will become 67 * 0.0625 = 4.1875 - yet there are no decimals in integer pixels which means it will also become 4. The effect that you will get posterization - setting your alpha channel to 8 means that you also reduce your color channels to 8 levels, this means instead = 256*256*256 different colors you will end up with a maximum of 8*8*8 = 512 different colors.

Well, as long as you keep your alpha at 8 you will not notice any difference but once you increase the alpha the desaster becomes obvious. Getting back from alpha 8 to alpha 255 means multiplying each channel by 16. This means that our old 64 pixel which was reduced to 4 becomes 4*16 = 64. Now that's great - same value as before! But the 67 pixel had also been reduced to 4 which means 4*16 = 64 - that's 3 smaller than 67. This means this information is lost forever and cannot be restored. And the eye can be quite unforgiving when it comes to certain subtle shades.

In order to show you the extend of this effect I've built a demo that visualizes the amount of information lossthat happens: It first reduces an image's alpha channel to a chosen value and then sets the alpha back to 255. What you will see is that for small alpha values there is some nasty posterization happening. But even if you just reduce the alpha to 254 the image will suffer information loss, you can see that by switching on the "show data loss" checkbox. What this does is to take a difference between the original and the restored image. Since the loss can be small there is an automatic multiplication involved to increase the contrast.

So what can you do when you have to preserve the image information? Well, you have to take the slow road and always keep the alpha channel separate from the image. This means that you maintain three bitmaps - one is used to store the RGB information, one stores the alpha channel and the third one is used to be displayed on screen by joining both of them together.

分享到:
评论

相关推荐

    音视频资料-图像处理术语解释:什么是PRGBA和Alpha预乘(Premultiplied Alpha ).rar

    "PRGBA"和"Alpha预乘(Premultiplied Alpha)"就是两个这样的关键术语,它们涉及到颜色混合和透明效果的实现。 首先,我们来理解PRGBA。这个术语是“Pre-Multiplied RGB with Alpha”的缩写,它是颜色通道的一种...

    D3D-study.rar_Alpha_d3d_d3d 2d

    Alpha颜色混合,也称为透明度或不透明度混合,是图像处理中的一种技术,它允许两个或多个图像的像素以不同程度的透明度叠加在一起,形成新的图像。这种技术的核心在于Alpha通道,一个额外的颜色通道,用于存储每个...

    游戏中用到的透明效果

    每个像素都包含一个颜色值和一个alpha通道,alpha通道决定了像素的透明度,值范围通常在0到1之间,0代表完全透明,1代表完全不透明。 1. **Alpha通道**:在C++中,我们可以使用OpenGl库来处理alpha通道。每个颜色...

    VS2008下的win32Alpha混合的例子

    在计算机图形学中,颜色通常由红、绿、蓝(RGB)三个分量表示,而Alpha通道则用于存储像素的透明度信息。一个像素的Alpha值范围通常在0到1之间,其中0代表完全透明,1代表完全不透明。Alpha混合就是利用这个Alpha值...

    VC 实现两张图片透明化并合成新图像.rar

    2. **Alpha通道**:Alpha通道是图像中的一个额外通道,用于表示像素的透明度。值0代表完全透明,255代表完全不透明。在处理透明图像时,我们需要对这个通道进行操作。 3. **GDI+库**:在VC++中,可以使用GDI+库来...

    dx9_alpha_blending_material.rar_Alpha

    除了这些基本步骤,还可以通过调整Alpha Blending的参数,实现更复杂的效果,比如预乘Alpha(premultiplied alpha)、颜色剪切(color clamping)和深度排序等。预乘Alpha处理了颜色和Alpha的关系,颜色剪切防止颜色...

    D2D透明块复制.rar

    3. Alpha混合:D2D在复制透明块时,会考虑源图像的Alpha值,根据源和目标像素的Alpha值进行混合,以达到正确的透明效果。这涉及到颜色的Alpha混合算法,如Alpha blending或Premultiplied Alpha blending。 三、源码...

    音视频资料-图像处理术语解释:灰度、色相、饱和度、亮度、明度、阿尔法通道、

    最后,Premultiplied Alpha(Alpha预乘)是一种优化的技术,它将颜色分量与Alpha值相乘,使得在混合透明图像时能减少错误和边缘锯齿现象。这种技术在3D图形渲染、视频合成等领域广泛应用。 综上所述,理解这些图像...

    AE层的通道合成器.pdf

    " Straight to Premultiplied"选项涉及Alpha通道的处理,它将直通Alpha(Straight Alpha)转换为预乘Alpha(Premultiplied Alpha),以更精确地处理带有透明度的图像。红、绿、蓝和Alpha通道是图像的基础,而Hue、...

    argb.rar_argb_argb显示效果

    1. 创建一个QImage对象,指定其大小并设置ARGB32或ARGB32_Premultiplied格式,这两种格式都支持Alpha通道。 2. 使用QPainter的begin()方法开始绘制操作,并将其绑定到目标设备,如QLabel、QWidget或其他可绘对象。 3...

    AE层的遮罩颜色消除.pdf

    这个效果可以帮助去除由于Alpha通道处理不当或者素材预乘Alpha(Premultiplied Alpha)导致的光晕,使得遮罩边缘更加平滑,减少与背景的冲突。 除了Remove Color Matting,还有其他几个相关的工具和概念值得了解: ...

    IOS应用源码之转换iPhonePNG图片为标准格式src.zip

    2. **颜色空间**:iOS系统倾向于使用Premultiplied Alpha(预乘Alpha)的颜色空间,这意味着像素的RGB值已经与Alpha通道的透明度相乘。非预乘Alpha的PNG图片在iOS上可能会出现色彩失真的问题,源码可能包含转换颜色...

    EditableContextMenu:WIP-Windows的可编辑上下文菜单外壳扩展

    使用PixelFormer并按照以下步骤操作: 在PixelFormer中打开具有透明度的16x16 PNG文件单击File -> Export 选择BMP作为“保存类型” 单击Save ,然后在以下窗口中选择A8:R8:G8:B8 (32 bpp) 检查Premultiplied alpha ...

    WebGL说明书(英文)

    - **Premultiplied Alpha**: 在WebGL中,预乘Alpha是一种处理透明度的技术,其中每个颜色通道都被Alpha值预先缩放。 - **Canvas APIs**: WebGL与HTML5 Canvas API紧密集成,可以利用Canvas API的功能来处理图像数据...

    occam一维反演

    C----------------------------------------------------------------------- program runocc C----------------------------------------------------------------------- c C OCCAM 2.0: Steven Constable IGPP/...

    QT使用 Linux framebuffer时候 支持QT本身不支持的其他格式(例如支持argb4444)的一种取巧方法

    return QImage::Format_ARGB4444_Premultiplied; } ``` 同时,还需要处理创建和初始化Framebuffer设备的部分。这通常包括打开Framebuffer设备节点,获取Framebuffer的信息(如宽度、高度、像素格式等),并根据...

    Nuke软件各种运算方法.pdf

    Alpha运算是Nuke软件中的一种基本运算方式,用于处理图像的透明度信息。常见的Alpha运算方式包括: * Copy(复制):将A的Alpha值复制到B上。 * Over(叠加):将A的Alpha值叠加到B上。 * In(内):将A的Alpha值...

    Spine 骨骼动画查看器Skeleton Viewer_官方文档中文版

    若勾选后显示正常,则应在导出 Atlas 文件时使用 premultiplied alpha 设置。 - **动画冲突**:当一个动画改变了某个骨架的状态时,这种改变会一直保留,直到被另一个动画或代码手动更改。为了避免这种情况,建议在...

    OpenGL ES 2.0 散射光demo

    例如,可以使用预乘阿尔法(premultiplied alpha)优化混合效果,或者使用低多边形模型和简化纹理来降低资源消耗。 总的来说,"OpenGL ES 2.0 散射光Demo"是一个学习和实践移动设备图形编程的好案例,它涵盖了顶点...

Global site tag (gtag.js) - Google Analytics