在Android 的SDK中提供了很多种绘图的方法,比较常用的是Drawable和Bitmap,Drawable中封装了大量的API,方便对图像进行处理,但是在实 际测试中Drawable的效率并不高,这里就针对Drawable和Bitmap的简单绘图进行了一个测试。
测试平台为WindEngine,采用不限制刷新率的方法测试FPS,每次渲染20张相同的图像,结论如下:
| No Scale | 50% Scale | 30% Scale | 150% Scale |
Drawable | 16.5 | 19.5 | 36 | 3 |
Bitmap | 17.6 | 34 | 55 | 7 |
表1-1 渲染效率测试
表1-1中的单位为FPS,越高表示每秒渲染得越多,越快。可以明显的看出,在不缩放的情况下,Drawable和Bitmap相差大约6%,差别不大, 但是当对图像进行缩放后,这个效率的差达到了50%!已经是很难容忍了,接下来看看对图像进行放大的渲染,可以明显看出两者放大后的效率差了不止一倍。
或许Google对Drawable的封装实实在在的方便了操作,我相信在传统APP中采用这种方法会得到很大的益处,但是在Game开发这种效率敏感的环境下,必须对每一行代码的效率进行深究。看来再接下来的开发中,要使用Bitmap来代替Drawable。
在Android中可以使用矩阵来完成图形的转换,但是采用动态转换的效率经过测试并不怎么高。还是按照上面的Demo,渲染一个正常图片需要17FPS 左右,渲染一张水平翻转的图片则只有14的FPS,效率差别还是挺大的。对于这种情况就需要采用“空间换时间”了,将需要处理的图像进行缓存。
Bitmap srcBitmap = ResourceHelper.loadBitmap(R.drawable.image );
Matrix srcMatrix = new Matrix();
srcMatrix.postScale(-1, 1);
srcMatrix.postTranslate(srcBitmap.getWidth(), 0);
bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), srcMatrix, false );
采用上面的代码,可以将翻转效果预先在loadResource方法执行,在正式的循环中将不再进行翻转操作,FPS恢复到了17,达到了目标。
Bitmap srcBitmap = ResourceHelper.loadBitmap(R.drawable.image );
int width = (int )(srcBitmap.getWidth() * 1.5f);
int height = (int )(srcBitmap.getHeight() * 1.5f);
bitmap = Bitmap.createScaledBitmap(srcBitmap, width, height, true );
按照上述的思路,对图像的缩放操作同样也可以采用创建图片的方式进行。通过上面的方法,调用Bitmap::createScaledBitmap方法, 按照预定义的比例缩放了一张图片,将使用插值设置为true,可以在loadResource阶段对图像进行缩放,并且带有了插值效果,FPS也达到了 8。很不错。
总结一下上面的东西,写得比较乱啊- - #。首先对比了Drawable和Bitmap的效率问题,从根本上直接忽略了Drawable。接下来针对Bitmap的各种功能进行了探讨。首先是 Bitmap在运行期进行缩放是不带线性插值效果的,缩放效果不理想,需要通过Bitmap::createBitmap方法在loadRousece阶 段来创建图像才可以。之后再次深入的讨论效率的问题,将Matrix效果集中在loadResource阶段进行,提高了渲染速度。
来自:http://isprain.spaces.live.com/blog/cns!52DA338FF6CDB2C1!159.entry