渲染大型Bitmap的小区域非常耗时

Luk*_*lor 7 java android bitmap

我有以下代码.

this.getGame().getGraphics().drawBitmap(Assets.playScreen_LaserBeamAnimation, new Rect(0, 0, 100, 750), new Rect(0, 0, 100, 750), null);
this.getGame().getGraphics().drawBitmap(Assets.playScreen_LaserBeamAnimation, new Rect(0, 200, 10, 800), new Rect(0, 0, 200, 600), null);
Run Code Online (Sandbox Code Playgroud)

第一个render语句0.6 - 1 second用于渲染.第二个围绕着1 millisecond.

位图很大:968 KB并加载以下代码:

public Bitmap readAssetsBitmap(String filename) throws IOException {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options(); 
            options.inPurgeable = true;
            Bitmap bitmap = BitmapFactory.decodeStream(assets.open(filename), null, options);
            if(bitmap == null) {
                WSLog.d(Game.GAME_ENGINE_TAG, this,"File cannot be opened: It's value is null");
                throw new IOException("File cannot be opened: It's value is null");
            }
            else {
                WSLog.d(Game.GAME_ENGINE_TAG, this,"File successfully read: " + filename);
                return bitmap;
            }
        } 
        catch (IOException e) {
            WSLog.d(Game.GAME_ENGINE_TAG, this,"File cannot be opened: " + e.getMessage());
            throw new IOException("File cannot be opened: " + e.getMessage());
        }

    }
Run Code Online (Sandbox Code Playgroud)

我希望读取图像并设置Bitmap需要一些时间,但渲染它的一个小区域不应该花这么长时间(而且神秘地它只是第一次渲染调用).

如何避免第一次渲染需要这么长时间?

注意:它不需要对缩放做任何事情(我相信).

Jas*_*son 0

看起来您正在尝试使用包含所有帧的大位图来绘制动画。如果是这种情况,那么缩小图像可能不适合您。

但是,如果图像中有 n 个离散帧,那么为什么不在加载图像时创建 n 个位图并在ArrayList<Bitmap>应用程序加载时将它们存储在 an 中呢?这样您就可以预切图像,而不必担心渲染时对图像进行切片。

在渲染时,您可以将当前位图替换为您想要绘制的位图,也可以在不缩放的情况下就地绘制图像(比缩放绘制快得多)。

这可能需要更多内存,但可能会提供显着的加速。


更新:关于为什么这么慢。Java 图形学真的很愚蠢。我的猜测是,在第一个示例(长示例)中,当它看到区域具有相同的比例时,它会迭代整个大图像,每当它找到给定区域中的像素时,它就会将其绘制在目的地地区。

在快速绘制中,我的猜测是,它看到比例不同,然后向后执行:对于目标区域中的每个像素,它会计算出原始图像中要引用的像素,并相应地混合到该正方形中。

由于目标区域中的像素要少得多,因此算法速度要快得多。

Java.Graphics 真的很糟糕。您是否研究过其他第三方图像处理库?