在Android上绘制高帧率的高分辨率动画
我有 30 多个单位图(320x240 像素),我想在 Android 设备上全屏显示它们,从而产生动画。目前,我使用 ImageView 和设置下一帧的计时器实现了动画,然后发送一条将应用下一帧的消息。结果帧速率非常低:< 2 帧/秒。
计时器:
animationTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Drawable frame = getNextFrame();
if (frame != null) {
Message message = animationFrameHandler.obtainMessage(1, frame);
animationFrameHandler.sendMessage(message);
}
}
}, 0, (int) (1000.0d / fps));
处理程序:
final Handler animationFrameHandler = new Handler() {
@Override
public void handleMessage(Message message) {
setImageDrawable((Drawable) message.obj);
}
};
由于我想实现高达 30 fps 的帧速率,我必须使用另一种机制并听说过 Canvas.drawBitmapMesh() 和OpenGL。
如果可能的话我想避免使用 OpenGL。
非常感谢您分享您的经验!
I've got 30+ single bitmaps (320x240 pixels) that I would like to display one after another in full screen on Android devices resulting in an animation. Currently I implemented the animation using an ImageView and a Timer that sets the next frame and then sends a message that will apply the next frame. The resulting frame rate is very low: < 2 fps.
The timer:
animationTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Drawable frame = getNextFrame();
if (frame != null) {
Message message = animationFrameHandler.obtainMessage(1, frame);
animationFrameHandler.sendMessage(message);
}
}
}, 0, (int) (1000.0d / fps));
The handler:
final Handler animationFrameHandler = new Handler() {
@Override
public void handleMessage(Message message) {
setImageDrawable((Drawable) message.obj);
}
};
Since I want to achieve frame rates up to 30 fps I have to make use of another mechanism and heard of Canvas.drawBitmapMesh() and OpenGL.
If possible I would like to avoid using OpenGL.
Thank you very sharing your experiences!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我现在的工作方法如下:
在开始动画之前,将每个帧加载到
List
中。重要提示:如果遇到OutOfMemoryError
,请调用System.gc()
– 这确实有助于将更多位图加载到内存中。然后运行一个线程,将下一帧发布到 View 实例,然后更新其画布。加载帧并开始动画
应用下一帧的线程
动画视图
My now working approach is the following:
Before starting the animation, load every frame into a
List<Bitmap>
. Important: CallSystem.gc()
if you're gettingOutOfMemoryError
s – that really helps loading more bitmaps into the memory. Then have a thread running that posts the next frame to a View instance that then update it's canvas.Loading the frames and starting the animation
Thread that applies the next frame
The animation view
您应该查看 FrameAnimation 类; http://developer.android.com/guide/topics /graphics/2d-graphics.html#frame-animation 使用 Android 动画制作帧动画。
尽管这可能仍然太慢。
如果您不想使用 OpenGL ES,另一种选择是像您提到的那样绘制到画布上。但只使用.drawBitmap,而不是drawBitmapMesh。创建一个 SurfaceView,它有一个线程,该线程应该以您想要的任何时间间隔在您的 Canvas 上绘制。
非常简单,只需阅读 Android 文档,信息就在那里。
You should look at the FrameAnimation class; http://developer.android.com/guide/topics/graphics/2d-graphics.html#frame-animation to do frame animation with Androids animation.
Though that might still be too slow.
The other alternative if you don't want to use OpenGL ES is to draw to the Canvas as you've mentioned. But just use .drawBitmap, not the drawBitmapMesh. Create a SurfaceView, which has a thread, that thread should draw on your Canvas at whatever interval you want.
It's pretty straightforward, just read the Android docs, the information is all there.
我会让其他人讨论执行此操作的最佳方法,但从您的帖子中立即跳到脑海中的一件事没有帮助,那就是使用 TimerTask 是执行此操作的一种糟糕方法,并且不适用于动画。
I'll let someone else go into the best way of doing this but one thing that immediately jumps to mind from your post that isn't helping is using TimerTask is a terrible way to do this and is not meant for animation.
可能对性能没有帮助,但如果这些位图是资源,您可能需要考虑使用
AnimationDrawable
。如果没有,请尝试扩展Drawable
并实现Animatable
接口。视图已经内置了对可绘制动画的支持,无需为此使用处理程序。提高性能的一种方法可能是将可绘制对象的位深度与当前窗口的位深度相匹配。 Romain Guy 曾就此问题和一般动画做过一次主题演讲:http://www.youtube.com/观看?v=duefsFTJXzc
Probably won't help with performance, but if those bitmaps are resources you might want to consider using an
AnimationDrawable
. If not, try to extendDrawable
and implement theAnimatable
interface. Views already have built-in support for animating drawables, no need to use a handler for that.One way to improve performance might be to match the bit-depth of the drawables to those of your current window. Romain Guy did a keynote on this and animations in general once: http://www.youtube.com/watch?v=duefsFTJXzc