我可以使用OPENGL进行逐帧动画吗?

时间:2012-09-16 06:46:00

标签: android opengl-es

我需要制作几个逐帧动画,每个动画最多包含150个全屏,480x800,帧,压缩JPEG。

当前10帧左右超出vm预算时,AnimationDrawable会自行挂起。

在计时器上加载新位图的SurfaceView提供了相当慢的帧速率,可能小于5 fps。

由于我是OpenGL的新手,我想问一下在我的情况下是否采用正确的方法?

谢谢! :)

编辑:

加载jpges
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    BitmapFactory.decodeResource(getResources(), R.drawable.y1).compress(Bitmap.CompressFormat.JPEG, 80, stream);
    byeArr.add( stream.toByteArray() );

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    BitmapFactory.decodeResource(getResources(), R.drawable.y2).compress(Bitmap.CompressFormat.JPEG, 80, stream);
    byeArr.add( stream.toByteArray() );

... and so on.

播放

@Override
public void onTick(long millisUntilFinished) {

    if ( i < byeArr.size() )
    {
    bitMap = BitmapFactory.decodeByteArray ( byeArr.get(i) , 0,  byeArr.get(i).length );
    }

加载25帧需要大约3-5秒。也许有办法加快速度?还有办法看看我有多少可用内存,即我可以加载多少帧?

由于


EDIT2: 通过实验发现它可以在一个阵列中保留大约350帧,这对于大约2个完整的动画非常有用。现在我只需要找到一种方法以某种方式将这些图片存储为字节,以便能够几乎实时加载它们,因为decodeResource有点慢。

edit3:在编辑2中,我确保我可以在一个数组中存储大约350帧,这对于一个动画来说足够了。

因此我可以将当​​前动画所需的帧加载到字节数组中并播放动画。

然而问题是通过

加载帧
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BitmapFactory.decodeResource(getResources(), R.drawable.y1).compress(Bitmap.CompressFormat.JPEG, 80, stream);
byeArr.add( stream.toByteArray() );

需要太长时间。所以我需要找到一种方法来加快速度。据说我需要将jpegs作为字节数组存储在res或assets中,您怎么看?

1 个答案:

答案 0 :(得分:3)

首先将动画转换为视频流,然后使用MediaMetadataRetriever.getFrameAtTime获取帧。如果正确的框架变成问题,您可能需要使用ffmpeg之类的库,请查看here

另一种解决方案 - 如果jpeg集的总分配大小足够小 - 可能是将jpeg作为字节数组保存在内存中,并在需要时通过BitmapFactory.decodeByteArray解码它们。这将有助于你1)vm预算2)慢速磁盘访问。

您可以使用以下方法从资源中获取原始数据。

byte[] getBytesFromResource(final int res) {
    byte[] buffer = null;
    InputStream input = null;

    try {
        input = getResources().openRawResource(res);
        buffer = new byte[input.available()];
        if (input.read(buffer, 0, buffer.length) != buffer.length) {
            buffer = null;
        }
    } catch (IOException e) {
        buffer = null;
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {}
        }
    }

    return buffer;
}