最有效的方式来显示一帧一帧动画的android [英] Most efficient way to show frame by frame animation android

查看:511
本文介绍了最有效的方式来显示一帧一帧动画的android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过在ImageView的变化图像,显示一帧一帧动画。我试图动画绘制在XML中,也不断变化的处理程序内的ImageView的位图。我也试过来存储只有三个位图一个数组列表内(以避免内存不足)的缓存机制,但非常低的改善。我需要遍历36图像完整的动画。我现在面临的问题是,在所有的方法我用我无法完成在50毫秒的时间内给出动画。这些图像的范围从250 kb的最小到540 KB最大。动画的FPS真的很低。随着应用程序的IOS版本已经准备好我不得不表现出动画一致的IOS版本。我在renderscript和OpenGL一个小白。有没有什么办法来显示一个平滑的动画为大型图像50-60ms。任何提示或建议高度AP preciated。动画的继承人的快照: 这里的链接以我的图片任何一个intrested。

I am trying to show frame by frame animation by changing images in a imageview. I tried animation drawable in xml and also changing the bitmap of the imageview inside a Handler. I also tried to store only three bitmaps inside a arraylist(to avoid out of memory) as a caching mechanism but really low improvement. I need to iterate 36 images for a full animation. The problem i am facing is that in all the methods I used I cannot complete the animation in the given timeframe of 50ms. The images range from 250 kb smallest to 540 kb maximum. The fps of animation is really low. As the ios version of the app is ready I am constrained to show animation consistent to the ios version. I am a noob in renderscript and opengl. Is there any way to show a smooth animation for large images in 50-60ms. Any hints or suggestions is highly appreciated. Heres a snapshot of the animation: Here's the link to my images for any one intrested.

推荐答案

我写了一个简单的活动,做最基础的事情:

I wrote a simple activity that does the most basic thing:

加载在一个线程中所有的位图,然后投递一个改变了ImageView的每40毫秒。

Loads all bitmaps in a Thread, then posts a change to an ImageView every 40ms.

package mk.testanimation;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
import java.util.ArrayList;

public class MainActivity extends Activity {
    ImageView mImageView;

    private int mImageRes[] = new int[]{
        R.drawable.s0,
        R.drawable.s1,
        R.drawable.s2,
        R.drawable.s3,
        R.drawable.s4,
        R.drawable.s5,
        R.drawable.s6,
        R.drawable.s7,
        R.drawable.s8,
        R.drawable.s9,
        R.drawable.s10,
        R.drawable.s11,
        R.drawable.s12,
        R.drawable.s13,
        R.drawable.s14,
        R.drawable.s15,
        R.drawable.s16,
        R.drawable.s17,
        R.drawable.s18,
        R.drawable.s19,
        R.drawable.s20,
        R.drawable.s21,
        R.drawable.s22,
        R.drawable.s23,
        R.drawable.s24,
        R.drawable.s25,
        R.drawable.s26,
        R.drawable.s27,
        R.drawable.s28,
        R.drawable.s29,
        R.drawable.s30,
        R.drawable.s31,
        R.drawable.s32,
        R.drawable.s33,
        R.drawable.s34,
        R.drawable.s35,
    };

    private ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(mImageRes.length);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final Handler handler = new Handler();
        mImageView = new ImageView(this);
        setContentView(mImageView);
        Thread important = new Thread() {
            @Override
            public void run() {
                long timestamp = System.currentTimeMillis();
                for (int i = 0; i < mImageRes.length; i++) {
                    mBitmaps.add(BitmapFactory.decodeResource(getResources(), mImageRes[i]));
                }
                Log.d("ANIM-TAG", "Loading all bitmaps took " + (System.currentTimeMillis() - timestamp) + "ms");
                for (int i = 0; i < mBitmaps.size(); i++) {
                    final int idx = i;
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mImageView.setImageBitmap(mBitmaps.get(idx));
                        }
                    }, i * 40);
                }
            }
        };
        important.setPriority(Thread.MAX_PRIORITY);
        important.start();
    }
}

这看起来pretty的体面的在我的Nexus 7,但它确实需要多一点的4S加载所有的位图。

This looked pretty decent on my Nexus 7, but it did take a little over 4s to load all the bitmaps.

您可以预先加载位图?

此外,它也救不了一吨,但你的PNG图片周围有透明的空间一堆填充。您可以剪裁他们,并降低内存位。否则玉米pressing的图像也会帮助(就像限制使用的颜色数)。

Also, it won't save a ton, but your pngs have a bunch of padding around the transparent space. You can crop them and reduce the memory a bit. Otherwise compressing the images will also help (like limiting the number of colors used).

理想情况下,在上述溶液中,你会回收位图他们后立即不再使用。

Ideally, in the above solution, you'd recycle the bitmaps immediately after they're no longer used.

此外,如果那也太内存沉重,你可以做你所说的,并有一个位图缓存,但我pretty的肯定这将需要超过3图像大。

Also, if that's too memory-heavy, you could do as you mentioned, and have a Bitmap buffer, but I'm pretty sure it'll need to be more than 3 images large.

祝你好运。

编辑:尝试2。 首先,我冒出的所有图像,以590x590。这剃光1MB左右关闭图像。然后,我创建了一个新的类,这是一个有点忙,并没有一个固定的帧速率,但只要他们愿意呈现的图像:

Attempt 2. First, I cropped all the images to 590x590. This shaved about 1mb off the images. Then I created a new class, which is a bit "busy" and doesn't have a fixed frame rate but renders the images as soon as they are ready:

package mk.testanimation;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;

import java.util.ArrayList;

public class MainActivity extends Activity {
    ImageView mImageView;

    private int mImageRes[] = new int[]{R.drawable.s0, R.drawable.s1, R.drawable.s2, R.drawable.s3, R.drawable.s4, R.drawable.s5, R.drawable.s6, R.drawable.s7, R.drawable.s8, R.drawable.s9, R.drawable.s10, R.drawable.s11, R.drawable.s12, R.drawable.s13, R.drawable.s14, R.drawable.s15, R.drawable.s16, R.drawable.s17, R.drawable.s18, R.drawable.s19, R.drawable.s20, R.drawable.s21, R.drawable.s22, R.drawable.s23, R.drawable.s24, R.drawable.s25, R.drawable.s26, R.drawable.s27, R.drawable.s28, R.drawable.s29, R.drawable.s30, R.drawable.s31, R.drawable.s32, R.drawable.s33, R.drawable.s34, R.drawable.s35};

    private ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(mImageRes.length);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final long timestamp = System.currentTimeMillis();
        final Handler handler = new Handler();
        mImageView = new ImageView(this);
        setContentView(mImageView);
        Thread important = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < mImageRes.length; i++) {
                    mBitmaps.add(BitmapFactory.decodeResource(getResources(), mImageRes[i]));
                }
            }
        };
        important.setPriority(Thread.MAX_PRIORITY);
        important.start();
        Thread drawing = new Thread() {
            @Override
            public void run() {
                int i = 0;
                while (i < mImageRes.length) {
                    if (i >= mBitmaps.size()) {
                        Thread.yield();
                    } else {
                        final Bitmap bitmap = mBitmaps.get(i);
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                mImageView.setImageBitmap(bitmap);
                            }
                        });
                        i++;
                    }
                }
                Log.d("ANIM-TAG", "Time to render all frames:" + (System.currentTimeMillis() - timestamp) + "ms");
            }
        };
        drawing.setPriority(Thread.MAX_PRIORITY);
        drawing.start();
    }
}

以上得到了渲染到近立即开始,前后历时不到4秒在我2012的Nexus 7。

The above got the rendering to start nearly immediately, and it took less than 4s on my 2012 Nexus 7.

作为最后的努力,我转换的所有图像到8位PNG,而不是32位。这带来了渲染,以在2秒!

As a last effort, I converted all the images to 8-bit PNGs instead of 32-bit. This brought the rendering to under 2 seconds!

我敢打赌,你最终得到的任何解决方案将从使图像尽可能小的好处。

I'll bet any solution you end up with will benefit from making the images as small as possible.

再次 - !好运气

这篇关于最有效的方式来显示一帧一帧动画的android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆