Android Spritesheet编程剪切:最佳实践

Android Spritesheet编程剪切:最佳实践,android,bitmap,sprite-sheet,Android,Bitmap,Sprite Sheet,我有一个由42帧组成的大精灵表(3808x1632)。 我将用这些帧呈现一个动画,我使用一个线程加载一个包含所有帧的位图数组,启动屏幕等待结束。 我没有使用SurfaceView(和画布的绘图功能),我只是在主布局的ImageView中逐帧加载。 我的方法类似于 实际上,完成这项工作几乎需要15秒,这是不可接受的 我使用这种函数: for (int i=0; i<TotalFramesTeapotBG; i++) { xStartTeapotBG = (i % fr

我有一个由42帧组成的大精灵表(3808x1632)。 我将用这些帧呈现一个动画,我使用一个线程加载一个包含所有帧的位图数组,启动屏幕等待结束。 我没有使用SurfaceView(和画布的绘图功能),我只是在主布局的ImageView中逐帧加载。 我的方法类似于 实际上,完成这项工作几乎需要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));
        }

for(int i=0;i使用a。将精灵剪切成单独的帧,并将其放入可绘制资源目录中。可以通过编程方式,也可以通过创建可绘制资源目录。然后使用来选择帧。

简单的答案是更好的内存管理

您正在加载的sprite表非常大,然后将其复制到一堆小位图中。假设sprite表不能再小了,我建议采用以下两种方法之一:

  • 使用单独的位图。这将减少内存副本以及Dalvik必须增加堆的次数。但是,这些好处可能会受到需要从文件系统中加载多个图像而不是一个图像的限制。这在普通计算机中是如此,但Android系统可能会得到不同的结果因为他们用光了闪存
  • 直接从您的sprite工作表中进行Blit。绘图时,只需使用类似的方法直接从sprite工作表中进行绘图。这会将您的文件加载量减少到一个较大的分配量,在您的活动生命周期中可能只需执行一次

  • 我认为第二个选项可能是两个选项中更好的一个,因为它在内存系统上更容易,GC的工作量更少。

    感谢stevehb的建议,我终于得到了:

    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, xStartTeapotBG+frameWidthTeapotBG, yStartTeapotBG+frameHeightTeapotBG); 
        Rect dst = new Rect(0, 0, frameWidthTeapotBG, frameHeightTeapotBG);  
        c.drawBitmap(framesBitmapTeapotBG, src, dst, null);         
        mVectorTeapotBG.add(bmFrame);
    }
    
    for(int i=0;i

    计算时间惊人地减少了!:)

    我使用了一种基于行和列的切片方法。然而,你的雪碧床单相当大。你必须认为你把整张纸都记在了记忆里。3808x1632x4是内存中图像的大小

    无论如何,我要做的是拍摄一张图像(比如128x128),然后告诉它Sprite(位图,4,2)构造函数中有4列和2行。然后你可以根据这个来切片和骰子。bitmap.getWidth()/4等。。。非常简单的东西。然而,如果你想做一些真实的事情,可以使用OpenGL和纹理


    哦,我也忘了提一些需要发生的事情。基本上,你可以保留一个索引计数器,从位图中切出一个矩形,然后在画布上从源矩形绘制到目标矩形。

    你的方法很清楚,我以前也曾在其他应用程序中使用过,但对于42帧的精灵表来说,自己制作这一切真的很无聊。我正在寻找一个自动过程,从spritesheet开始,然后自动完成其余的所有工作。只需像以前一样,以编程方式将其切碎,然后将位图输出到文件中。查看[Bitmap.compress()](,int,java.io.OutputStream))。事实上,在我看来,您的第二个选项似乎更好。我正试着去做,我编辑了我的第一个问题。
    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, xStartTeapotBG+frameWidthTeapotBG, yStartTeapotBG+frameHeightTeapotBG); 
        Rect dst = new Rect(0, 0, frameWidthTeapotBG, frameHeightTeapotBG);  
        c.drawBitmap(framesBitmapTeapotBG, src, dst, null);         
        mVectorTeapotBG.add(bmFrame);
    }