在Canvas上绘制旋转的位图很慢:还有其他选择吗?

问题描述

| 我正在开发一个动态壁纸应用程序,它将绘制一个模拟时钟。到目前为止,我到达了使用三个位图绘制时钟的位置:刻度盘,时针和分针。 当我绘制小时和分钟时,我会这样做(伪代码):
// without this it looks weird after rotate
Paint smoothPaint = new Paint(FILTER_BITMAP_FLAG);
canvas.drawBitmap(dialBitmap,null);

canvas.rotate(ANGLE_FOR_HOUR_HAND,w/2,h/2);
canvas.drawBitmap(hourBitmap,smoothPaint);

canvas.rotate(ANGLE_FOR_MINUTE_HAND,h/2);
canvas.drawBitmap(minuteBitmap,smoothPaint);
除了我得到的帧率非常低:大约13 fps之外,这种方法还可以。 如果我关闭位图过滤,它会增加到约24 fps,但对我来说仍然很低。 我知道Canvas上的2d绘图不会以任何方式加速,但是我仍然想问问我还有其他选择可以加快此代码的速度吗?以某种方式本地绘制到位图?也许还有其他东西吗? 使用OpenGL是一个选项,但由于LiveWallpapers不支持GL绘图,所以它不是那么简单,因此我需要使用第三方黑客(我知道存在)来实现我不愿意做的事情...     

解决方法

您问:“还有其他选择吗?”。您有两个: 不要使用位图。例如,第二个Cube SDK示例以25 fps弹出一个旋转的20行十二面体。 正如您已经提到的,有时您可以在动态壁纸中使用“ hack”来处理特殊用途的图形。我建议您至少看一下以下三个...有一天您可能会发现它们很有用:AndEngine(具有动态壁纸扩展),LibGDX(允许您在桌面环境中进行原型制作;动态壁纸功能仍在开发中, methinks)和GLWallpaperService(专门设计用于将GLSurfaceView引入动态壁纸)。 在您的帖子中,您说24 fps对您来说“仍然很低”。据我了解,24 fps大约是人类感知的极限(无论如何,这是Flash默认使用的功能)。我建议即使您可以,也不要再提高电池寿命了。 编辑:要考虑的另一个“ hack”:renderscript。这就是许多手机随附的一些复杂壁纸(Galaxy,Grass,Water)的工作方式。在此处查看启用Java文件的渲染脚本:https://android.googlesource.com/platform/packages/wallpapers/Basic/+/master/src/com/android/wallpaper     ,如何在分针每次更改时将您的手势配置呈现为中间位图,然后在每个帧上将静态位图呈现给画布?     ,发现了一些有助于提高帧速率的东西,将在此处作为对我自己的答复:) 首先是使用Canvas.drawBitmap(Bitmap,Matrix,Paint)重载来提供矩阵,而不是使用canvas.save()+ canvas.rotate()+ canvas.restore()-效率更高。 第二:减小位图的大小。之前,它们被填充为接近hdpi(480pix)的屏幕大小,并在其周围添加了透明像素。在我裁剪掉这些透明像素并修改了渲染代码以解决此问题之后,旋转变得更加高效(如预期的那样)。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...