低帧率写位图到画布 [英] Low framerate writing bitmaps to the canvas

查看:121
本文介绍了低帧率写位图到画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个是通过绘制每一帧到画布上运行一个环形动画动态壁纸。我有一个单一的图像,尺寸的屏幕的精确尺寸。我有一套400帧大小正好适合对屏幕的底部三分之一;这是在动画发生。这里是code,显示它们:

I have a live wallpaper that is running a looped animation by drawing each frame to the canvas. I have one single image, sized to the exact dimensions of the screen. I have a set of 400 frames sized exactly to fit about the bottom third of the screen; this is where the animation occurs. Here is the code that displays them:

public void updateBG() {
    mHandler.removeCallbacks(mUpdateDisplay);
    if (mVisible) {
        mHandler.postDelayed(mUpdateDisplay, 40);
    }

    if (imagesLoaded < totalFrames) {
        ShowLoadingProgress();
    } else {
        SurfaceHolder holder = getSurfaceHolder();
        Canvas c = null;
        try {
            c = holder.lockCanvas();
            if (c != null) {
                Paint p = new Paint();
                p.setAntiAlias(true);
                c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
                Rect destinationRect = new Rect();
                destinationRect.set(0, 0, canvasWidth, canvasHeight);


                if (animStartX > 0 || animEndX > 0 || animStartY > 0 || animEndY > 0) {
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[totalFrames], 0, bitmapArray[totalFrames].length), null, destinationRect, p);
                    Rect destinationRectAnim = new Rect();
                    destinationRectAnim.set(animX, animY, animX+animWidth, animY+animHeight);
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRectAnim, p);
                } else {
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRect, p);
                }

            }
        } finally {
            if (c != null)
                holder.unlockCanvasAndPost(c);
        }
        bgcycle++;
    }
}

这code为约10-12 FPS上的Xperia离子(双核1.5GHz的CPU)运行,更糟糕的旧设备上。它要好多了,当我以一半的屏幕分辨率保存整个帧。它实际上变得更糟,当我开始使用全帧屏幕分辨率(这应该已经消除了需要插每一帧)。然后,当我开始使用这种code,这将写入两个位图(presumably,因为它无法从上次运行的画布上半部​​分保存)得到更糟。

This code is running at approximately 10-12 FPS on an Xperia Ion (dual-core 1.5 GHz cpu) and worse on older devices. It was going much better when I saved entire frames at half the screen resolution. It actually got worse when I started using full frames at the screen resolution (which should have eliminated the need to interpolate on each frame). It then got even worse when I started using this code, which writes two bitmaps (presumably because it can't save the top half of the canvas from the last run).

我如何优化呢?我宁愿不保存完整的帧像刚才保存的动画部分的每一帧确实减少了内存使用情况。有什么感觉真的错了这里,特别是考虑到这是与它背后的权力运行3GHz的。我经常看一个450 MHz奔腾III的电影。有什么明显的是我做错了吗?是手机还是试图插补图像,即使它们是正确的大小?

How can I optimize this? I'd rather not save full frames as just saving the animated part for each frame really reduces memory usage. Something feels really wrong here, especially given that this is running with 3GHz of power behind it. I used to watch movies on a 450 MHz Pentium III. Is there something obvious that I'm doing wrong? Is the phone still trying to interpolate the images even though they are sized correctly?

推荐答案

您的每一帧解码您的位图,它的价格昂贵,它会产生垃圾将触发选区。您还渲染使用软件渲染。这里是您的解决方案,依次是:

You are decoding your bitmap on every frame, it's expensive and it will generate garbage that will trigger GCs. You are also rendering using software rendering. Here are your solutions, in order:


  • 请不要再德code每一帧位图

  • 重用位图对象(见BitmapFactory.Options.inBitmap)

  • 使用硬件加速(直接呈现为一个视图,而不是SurfaceView。)软件插值是非常昂贵的。

这篇关于低帧率写位图到画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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