最近做的flashplayer的16bpp canvas 做line gradient渐变的时候出现的一个问题,例如我在RGBA=(0,0,0,FF)与RGBA(255,255,255,255)间做 line gradient,发现出现32级条纹,没个条纹为渐变的颜色值。
首先解释下为什么会是32级,因为 bpp=16bit的canvas 最多只有32阶的alpha混合后的颜色值。所以才会出现32级条纹。
即使我在做line gradient的时候是256级的alhpa, 但是最后转成16bpp就还是只有32阶。
开始我还以为是自己的渐变做法有问题,后来发现一个开源的flashplayer,里面却不能面线的感觉32阶的条纹,显得很平滑,
然后看看代码基本大同小异,最后在写入16bpp canvas的时候做了抖动处理,效果不错,贴出来与大家分享下,
当我们24 bpp 转16bpp的时候可以借鉴。
const UI8 ditherNoise16[4*4]={
7,0,5,1,
2,6,4,3,
4,3,7,2,
0,6,1,5,
}; 这个是抖动模板,里面数值的意思我还没搞明白,代码里的关于这个模板的注释是 // Random dither
#define PACK_RGB565(R,G,B) (((UI16)(((((UI16)(R))>>3)<<10)|((((UI16)(G))>>3)<<5)|((B)>>3))))因为windows canvas 16bpp似乎是555的,这个可以式情况而定。
跟据y坐标来选取抖动模板:
noise = ditherNoise16+(y&0x3)*4;
UI16 d=noise[i&0x3];
p1=PACK_RGB565((scanColor->Red+d),(scanColor->Green+d),(scanColor->Blue+d));
p1为计算出来的像素值,这个效果还不错,基本能消除 24bpp -16bpp出现的条纹状。
不知道在图形学中这个角什么以后有机会再研究,
写篇文章以记之,献给和我为同样问题而困扰的同仁。