大家好,我要介绍的所有知识点都是WINCE/windows触摸屏DUI开源框架constvar(点击下载代码)开发过程中遇到的比较有讨论价值的问题。
本文要讨论的是BMP位图的ALPHA运算,及资源的打包等。
1.图片资源打包处理一些值得注意的地方
为了使美工人员编辑图片方便,我们使用的图片资源都是带透明PNG格式的。PNG制作方便并且预览效果很直接,而32位BMP虽然效果不让于PNG,但制作和看起来确实很坑爹。
WINCE/windows程序运行的时候最终使用的终究是BMP,所以我们采用的方法是用PNG作资源,然后用CVUI界面编辑好界面的时候,把PNG转成32位带ALPHA通道的图片了。打包的时候,则可选择性的对不重要的界面用ZLIB算法进行压缩。这样的好处就是压缩的资源(裸BMP数据)只需解压就可以用了,一些使用频繁的界面则可以不压缩直接打包,读的时候不用解压会比节省解压的时间。
对于只能支持16位色深度的机器来说(一般都是565格式), 565 bmp的ALPHA混合也是避免不了的。但是565BMP本身不带ALHPA通道,所以我们从透明PNG转成565时,把转好的ALPHA(32级)必须单独保存.每一个像素的ALPHA虽然用5位能保存,但是为了防问ALPHA速度,就用一个字节保存。 这也就意味着一个565的像素点实际上用3个字节表示,2个字节的RGB数据,1个字节的ALPHA数据。 这样就能实现565图片的透明了。 另外在PNG转32位BMP再转565BMP+ALPHA的时候,用到了图像减少失真(水波纹)的误差扩散算法。
2. 565和32位图片的ALPHA混合
从资源包读取到565和32图片数据,如果没有加速指令支持,565就把数据由16位转32位,G的6位移到高16位去,搜一下0X07E0F81F 这个掩码,相关的文章很多。
dwP1 = *pDst;
dwP2 = *pSrc++;
dwP1 = (dwP1 | (dwP1<<16)) & 0X07E0F81F;
dwP2 = (dwP2 | (dwP2<<16)) & 0X07E0F81F;
dwP3 = (((dwP2 - dwP1)*a2>> 5) + dwP1) & 0X07E0F81F;
*pDst++= WORD((dwP3>> 16) | (dwP3 & 0XFFFF));
32位ARGB的话,也有一些小技巧, 下面的种一次计算2路的是从网上见到的一种:
dwSrc = *pSrc++;
dwDst = *pDst;
a= dwSrc>>24;
a1= 255-a;
dwRB = (dwSrc &0X00FF00FF)*a + (dwDst& 0X00FF00FF)*a1;
dwAG = ((dwSrc &0XFF00FF00)>>8)*a + ((dwDst & 0XFF00FF00)>>8)*a1;
*pDst++= ((dwRB & 0XFF00FF00) >> 8) | (dwAG & 0XFF00FF00);
总之ALPHA不用加速指令招数也就那几招,可以说很有限。并且总的来说改善空间很小了,关键的还是要在控制混合运算的次数上下工夫。这就牵涉到脏矩形和对象的维护了,后面会重点讨论这些。
ALPHA混合有一些值得注意的比如像GDI的设置关键色掩码透明,直接COPY,常数ALPHA混合,ALPHA叠加等,这些在实现界面时都会碰到,并且要择情况选择合适的,让效率达到最佳。这些在框架中都有实现,有需要的同学可以自己去查阅。