举报
本来是在做数据结构的练习题,写着写着,出于对模板类的反感,不知道怎么就走神了。 然后开始研究图像的混合,倒是有点收获,记下来再说:) 只是自己的一些简单的心得体会,所以不免会有错误。发现错误我会及时修改……发现不了的话……-v- 所谓图像混合,就是把一副图绘制到另外一副图像上的时候产生的问题。最简单的情况是覆盖,新的图像把旧的图像替换了。当我们需要一些漂亮的效果时,替换显然不能满足要求。 常听到的Alpha混合(AlphaBlending)就是一种漂亮的混合方式,它可以产生透明的效果。 两个象素以一个固定的Alpha值混合的公式很简单: 象素A各色分量*Alpha/255 + 象素B各色分量*(255-Alpha)/255 = 混合后的各色分量 至于为什么Alpha的上限是255,原因很简单,目前我所知的显示设备中,单色分量取值范围最大0~255,所以Alpha值多于255是无意义的。 16bit色常见的是565模式,颜色数据位不是平均分配给RGB三色分量上的,拆开再计算然后合并,速度很慢。因此采用一定的处理不需要拆分合并,然后再避免浮点运算或乘除运算后,可以加快Alpha混合的处理速度。16bit色的Alpha值只要取到2的5次方32即可,范围再大效果也不明显。至于加速的具体算法,我没有详细学习过,汇编苦手啊……-v- 24bit色不用拆分再合并,直接计算各颜色分量混合值,速度也凑合。可以考虑生成一个64k的颜色表,记录不同Alpha值的颜色分量,靠查表来避免浮点乘除运算。其他提速方法我就不知道了…… 32bit色有些不同,因为每个颜色值都包含各自的Alpha分量,开头的公式显然不太适合。由于没有看到过明确的说法,我只好自己猜测32bit色混合公式。 假设象素B是目标图像上的点,象素A是源图,将A画到B上的,混合公式如下: 象素A各色分量*(Alpha_A/255) + 象素B各色分量*(255-Alpha_A)/255) = 混合后的各色分量 混合后象素采用象素B的Alpha值。 也有文章说,混合时象素B的颜色分量要用象素B的Alpha值来计算,公式是这样的: 象素A各色分量*(Alpha_A/255) + 象素B各色分量*Alpha_B/255 = 混合后的各色分量 不过这么一来,混合后的32bit颜色值的Alpha分量该做何取舍呢? 由于自己还没有实现支持32bit色的图像库(因为图像缩放的算法问题还没有解决-v-),不知道怎样的混合公式更好,只能日后实践后再说了。 接下来是两种理论上很简单的颜色混合方式,加法混合与减法混合。 这是将两种颜色按简单的加减运算混合的方式。比如加法混合的公式: 象素A各色分量+象素B各色分量 = 混合后各色分量 注意写代码的时候,如果求和的值不能大于当前颜色模式下该色分量最大值。例如24bit色模式下求和大于255的话,取255。减法公式依此类推,也要注意相减后不能出现负值。 这样的混合方式我以前没有多留意过,其实这种方式很有用处。因为相对于Alpha混合,它的运算比较简单,速度上有一定优越性。有些图片使用这样的方式混合在背景上,可以体现出均匀过渡的半透明效果。比如加法混合,图像颜色越接近于黑色,其对于目标图像影响就越小,黑色是完全透明的。因此某种程度上,可以用这种方式来平滑图像的边缘,而不必给图片加上诸如Alpha通道一类的额外数据,大大提高绘图效率。 以前很多游戏的光影效果都是采用加法混合,感觉也挺好。看来并非只有32bit色才能实现均匀的过渡~ 最后说一下光栅操作(Raster operations),也是一种常见的图像混合运算。GDI的BitBlt函数最后一个参数,就是用来指定位块传送时执行的光栅操作类型。 光栅操作的类型很多,但其共同特征是,混合颜色时不是考虑各色的分量,而是将颜色值进行逐位运算。例如采用AND运算符或者OR运算符来合并两个颜色,可以产生一些很奇妙的效果。 在只能显示灰度的年代,混合时的光栅操作可以用来实现图像的局部透明,反色等各种效果。不过我了解的有限,不能完全领会光栅操作的各种功能,还有待进一步实践了:) 虽然图像混合的相关操作还有很多很多,目前以我的一知半解也只能说到这里了……这段文字算是一个小小的总结……貌似是没有多少营养的文字-v-还是赶快看数据结构吧……
本版积分规则 发表回复 回帖后跳转到最后一页
Archiver|手机版|小黑屋|EMAX Studio
GMT+8, 2025-8-24 02:24 , Processed in 0.012466 second(s), 18 queries .
Powered by Discuz! X3.4
© 2001-2017 Comsenz Inc.