Spritesheet programmatically cutting: best practices

↘锁芯ラ 提交于 2019-11-27 20:57:20

The short answer is better memory management.

The sprite sheet you're loading is huge, and then you're making a copy of it into a bunch of little bitmaps. Supposing the sprite sheet can't be any smaller, I'd suggest taking one of two approaches:

  1. Use individual bitmaps. This will reduce the memory copies as well as the number of times Dalvik will have to grow the heap. However, these benefits may be limited by the need to load many images off the filesystem instead of just one. This would be the case in a normal computer, but Android systems may get different results since they're run off flash memory.
  2. Blit directly from your sprite sheet. When drawing, just draw straight from sprite sheet using something like Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint). This will reduce your file loads to one large allocation that probably only needs to happen once in the lifetime of your activity.

I think the second option is probably the better of the two since it will be easier on the memory system and be less work for the GC.

Zappescu

Thanks to stevehb for the suggestion, I finally got it:

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);
}

The computation time falls incredibly! :)

Use a LevelListDrawable. Cut the sprites into individual frames and drop them in your drawable resource directory. Either programmatically or through an xml based level-list drawable create your drawable. Then use ImageView.setImageLevel() to pick your frame.

I use a method of slicing based on rows and columns. However your sprite sheet is rather huge. You have to think you are putting that whole sheet into memory. 3808x1632x4 is the size of the image in memory.

Anyway, what I do is I take an image (lets say a 128x128) and then tell it there are 4 columns and 2 rows in the Sprite(bitmap, 4, 2) constructor. Then you can slice and dice based on that. bitmap.getWidth() / 4 etc... pretty simple stuff. However if you want to do some real stuff use OpenGL and use textures.

Oh I also forgot to mention there are some onDraw stuff that needs to happen. Basically you keep an index counter and slice a rectangle from the bitmap and draw that from a source rectangle to a destination rectangle on the canvas.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!