android - Spritesheet 以编程方式切割 : best practices

原文 标签 android bitmap sprite-sheet

我有一个由 42 帧组成的大 Sprite 表(3808x1632)。
我会用这些帧呈现一个动画,我使用一个线程来加载一个包含所有帧的位图数组,一个启动画面等待它的结束。
我没有使用 SurfaceView(和 Canvas 的绘图功能),我只是在主布局的 ImageView 中逐帧加载。
我的做法类似于Loading a large number of images from a spritesheet
完成实际上需要将近 15 秒,这是 Not Acceptable 。

我使用这种功能:

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

frameBitmapTeapotBG 是大 Sprite 表。
看的更深一点,我在logcat中看到createBitmap函数需要很多时间,可能是因为spritesheet太大了。
我发现在某个地方可以在大 Sprite 表上创建一个窗口,使用 rect 函数和 Canvas ,创建要加载到数组中的小位图,但并不是很清楚。我说的是那个帖子:cut the portion of bitmap

我的问题是:我怎样才能加快 Sprite 表的切割速度?

编辑:
我正在尝试使用这种方法,但我看不到最终动画:
    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);
    }

可能是位图 bmFrame 没有正确管理。

最佳答案

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

你加载的 Sprite 表很大,然后你把它复制成一堆小位图。假设 Sprite 表不能更小,我建议采取以下两种方法之一:

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

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

    关于android - Spritesheet 以编程方式切割 : best practices,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7341017/

    相关文章:

    android - 更改选项卡后,软键盘仍然可见

    android - Android应用程序(应用程序类扩展)-一段时间后为空对象

    android - ViewPager不显示任何内容

    android - 生成应用时显示错误

    android - 位图压缩不会改变位图字节大小

    c++ - fstream 跳过字符而不读取位图

    ios - 重新启动场景时崩溃

    android - 从Android中的位图图像识别对象的形状?

    iphone - Cocos2d - 我可以将多个 Sprite 帧加载到帧缓存中吗

    具有一组 div 的图像的 CSS spritesheet