Spritesheet以编程方式切割:最佳实践

Zap*_*scu 3 android bitmap sprite-sheet

我有一个由42帧组成的大型spritesheet(3808x1632).我会用这些帧呈现一个动画,我使用一个线程来加载一个包含所有帧的位图数组,并用一个闪屏等待它的结束.我没有使用SurfaceView(和画布的绘图功能),我只是在我的主布局中的ImageView中逐帧加载.我的方法类似于从spritesheet中加载大量图像 完成实际需要大约15秒,这是不可接受的.

我用这种功能:

for (int i=0; i<TotalFramesTeapotBG; i++) {
            xStartTeapotBG = (i % framesInRowsTeapotBG) * frameWidthTeapotBG; 
            yStartTeapotBG = (i / framesInRowsTeapotBG) * frameHeightTeapotBG;
            mVectorTeapotBG.add(Bitmap.createBitmap(framesBitmapTeapotBG, xStartTeapotBG, yStartTeapotBG, frameWidthTeapotBG, frameHeightTeapotBG));
        }
Run Code Online (Sandbox Code Playgroud)

framesBitmapTeapotBG是一个很大的spritesheet.看得更深,我在logcat中读到createBitmap函数需要花费很多时间,可能是因为spritesheet太大了.我找到了一个可以在大spritesheet上创建窗口的地方,使用rect函数和canvas,创建要在数组中加载的小位图,但它并不是很清楚.我在谈论那篇文章:削减位图的一部分

我的问题是:如何加速spritesheet切割?

编辑:我正在尝试使用这种方法,但我看不到最终的动画:

    for (int i=0; i<TotalFramesTeapotBG; i++) {
        xStartTeapotBG = (i % framesInRowsTeapotBG) * frameWidthTeapotBG; 
        yStartTeapotBG = (i / framesInRowsTeapotBG) * frameHeightTeapotBG;
        Bitmap bmFrame = Bitmap.createBitmap(frameWidthTeapotBG, frameHeightTeapotBG, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmFrame); 
        Rect src = new Rect(xStartTeapotBG, yStartTeapotBG, frameWidthTeapotBG, frameHeightTeapotBG); 
        Rect dst = new Rect(0, 0, frameWidthTeapotBG, frameHeightTeapotBG);  
        c.drawBitmap(framesBitmapTeapotBG, src, dst, null);         
        mVectorTeapotBG.add(bmFrame);
    }
Run Code Online (Sandbox Code Playgroud)

可能没有正确管理Bitmap bmFrame.

Ste*_*ell 6

简短的回答是更好的内存管理.

你加载的精灵表是巨大的,然后你将它复制成一堆小位图.假设精灵表不能更小,我建议采用以下两种方法之一:

  1. 使用单个位图.这将减少内存副本以及Dalvik增加堆的次数.但是,这些好处可能受限于需要从文件系统加载许多图像而不仅仅是一个.在普通计算机中就是这种情况,但Android系统可能会因为闪存运行而得到不同的结果.
  2. 直接从您的精灵表单中进行Blit.绘图时,只需使用类似的东西从精灵表中直接绘制Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint).这会将文件加载减少到一个大的分配,可能只需要在活动的生命周期中发生一次.

我认为第二种选择可能是两者中较好的选择,因为它在内存系统上会更容易,而对GC的工作则更少.