Spritesheet以编程方式切割:最佳做法
我有一个由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));
}
framesBitmapTeapotBG是大的spritesheet。 更深入地看,我已经在logcat中读到了createBitmap函数花了很多时间,也许是因为spritesheet太大了。 我发现某处我可以在大的spritesheet上创建一个窗口,使用rect函数和画布,创建小型位图来加载数组,但它并不十分清楚。 我在谈论这个帖子:剪掉位图的一部分
我的问题是:我怎样才能加快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);
}
可能位图bmFrame的管理不正确。
简短的回答是更好的内存管理。
你正在加载的精灵表非常庞大,然后你将它复制到一堆小的位图上。 假设精灵表不能更小,我建议采取以下两种方法之一:
Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
等直接从精灵Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
。 这会将您的文件加载减少到一个大的分配,这可能只需要在活动的整个生命周期中进行一次。 我认为第二种选择可能是两者中较好的一种,因为它在内存系统上会更容易,并且对于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);
}
计算时间令人难以置信! :)
使用LevelListDrawable。 将精灵分割成单独的框架并将它们放入可绘制资源目录中。 以编程方式或通过基于xml的可绘制级别列表创建绘图。 然后使用ImageView.setImageLevel()来选择你的框架。
链接地址: http://www.djcxy.com/p/68953.html