在画布上绘制旋转的位图很慢:还有其他选项吗?

时间:2011-04-14 15:54:58

标签: android canvas bitmap live-wallpaper

我正在开发一个可以绘制模拟时钟的动态壁纸应用程序。到目前为止,我达到了使用三个位图绘制时钟的程度:拨号,时针,分针。

当我画出小时和分钟时,我这样做(伪代码):

// without this it looks weird after rotate
Paint smoothPaint = new Paint(FILTER_BITMAP_FLAG);
canvas.drawBitmap(dialBitmap, 0, 0, null);

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

canvas.rotate(ANGLE_FOR_MINUTE_HAND, w/2, h/2);
canvas.drawBitmap(minuteBitmap, 0, 0, smoothPaint);

除了我的帧速率非常低之外,这种方法还可以:大约13 fps。 如果我关闭位图过滤,它会增加到大约24 fps,但对我来说仍然很低。

我知道Canvas上的2d绘图没有以任何方式加速,但仍然想问我有没有其他选项来加速这段代码?以某种方式原生地绘制位图?还有别的吗?

使用OpenGL是一个选项,但它不是那么简单,因为LiveWallpapers不支持GL绘图,所以我需要使用第三方黑客(我知道存在),我宁愿不做...

3 个答案:

答案 0 :(得分:2)

“还有其他选择吗?”你问。你有两个:

  1. 请勿使用位图。例如,第二个Cube SDK示例以25 fps弹出一个旋转的20行十二面体。
  2. 正如您所提到的,有时您可以在动态壁纸中使用“hack”作为专用图形。我建议你至少看看以下三个......你可能会发现它们有用一天:AndEngine(有一个动态壁纸扩展),LibGDX(允许你在桌面环境中进行原型设计;活动墙纸设施仍在开发中, methinks)和GLWallpaperService(专门用于将GLSurfaceView带入动态壁纸)。
  3. 在你的帖子中,你说24 fps对你来说“仍然很低”。据我所知,24 fps大约是人类感知的极限(无论如何,这是Flash默认使用的)。我建议你不要高,即使你可以,为了保持电池寿命。

    编辑:另外一个“黑客”要考虑:renderscript。这就是许多手机配备的复杂壁纸(Galaxy,Grass,Water)的工作方式。请参阅renderscript在此处启用java文件:https://android.googlesource.com/platform/packages/wallpapers/Basic/+/master/src/com/android/wallpaper

答案 1 :(得分:1)

每次分针更改时,如何将手部配置渲染到中间位图,然后在每个帧上将静态位图渲染到画布上?

答案 2 :(得分:0)

发现一些有助于提高帧率的事情,会在这里作为对自己的答案发布:)

首先使用 Canvas.drawBitmap(Bitmap,Matrix,Paint)重载来提供矩阵,而不是使用 canvas.save() + canvas .rotate() + canvas.restore() - 效率更高。

第二:减小位图的大小。早些时候,他们被填充到接近屏幕尺寸的hdpi(480pix),周围添加了透明像素。在我将这些透明像素裁剪掉并修改渲染代码以解决这个问题之后,旋转变得更有效率(正如预期的那样)。