Reputation: 18734
I am trying to animate some movements of a person on my device. I have created a sprite sheet, which ends up being 1.23Mb. The image dimensions is 5000 by 1500 pix. The sheet has 8 rows, each is it's own action. (Walk on, bow, jump...). The longest action is 32 images. So the image is basically 32 columns, by 8 rows. So, now I load it:
As soon as I do this:
private Bitmap bmp;
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.myImage);
I get an error:
Thread [<1> main] (Suspended (exception OutOfMemoryError))
BitmapFactory.decodeResource(Resources, int, BitmapFactory$Options) line: 385 BitmapFactory.decodeResource(Resources, int) line: 404
GameView.(Context) line: 25 FightActivity.onCreate(Bundle) line: 13 FightActivity(Activity).performCreate(Bundle) line: 4465
Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1049
ActivityThread.performLaunchActivity(ActivityThread$ActivityClientRecord, Intent) line: 1920
ActivityThread.handleLaunchActivity(ActivityThread$ActivityClientRecord, Intent) line: 1981 ActivityThread.access$600(ActivityThread, ActivityThread$ActivityClientRecord, Intent) line: 123
ActivityThread$H.handleMessage(Message) line: 1147
ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 137 ActivityThread.main(String[]) line: 4424
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 511 ZygoteInit$MethodAndArgsCaller.run() line: 784
ZygoteInit.main(String[]) line: 551 NativeStart.main(String[]) line: not available [native method]
Am I limited to a certain file size? Seems strange? And if so, is my only option to split the sprites onto separate 'action' images, as opposed to a sequence of action images per row in one large sprite sheet?
Hope someone can assist a novice.
Upvotes: 0
Views: 1564
Reputation: 962
Have a single spritesheet for every animation in your character, hold a reference to common ones, and load as needed. This is flexible enough that your animation won't lag, except on bitmap change if you need to load it from memory, for example when you change from running to idle or something, (although those two are common enough that you would hold them in memory for a long time).
Increasing VM heap size is only a partial solution, and many devices won't have your needed heap size if you're holding bitmaps so big. Like they say above, image file size on disk is only important for deploying your application on Google Play (users will download less) but on ram the image is completely raw, which means every single pixel counts (example: a completely red 128x128 bitmap takes up the same space as a completely colorful one, having both exact same color depth).
I propose a solution for you, which is using this awesome software (I've no affiliation to it, except that I use it myself and it's great) that'll create your spritesheets in no time and export coordinates in various formats for you to use. TexturePacker.
Upvotes: 1
Reputation: 484
Depending on the complexity of the images, another answer may be to use vector graphics. There are numerous libraries with varying levels of documentation, and licensing requirements.
Example; http://www.andengine.org/
https://play.google.com/store/apps/details?id=org.anddev.farmtower.eco (AndEngine used on this game)
Upvotes: 0
Reputation: 5537
A simple calculation gets you the answer. Assuming 32-bits per pixel, you have ((5000x1500)pixels) * (32 bits per pixel) / (8 bits per byte) / (1024 * 1024 bits per Mb) = 28MB.
I did a Google search and I'm seeing default heap sizes for different versions of Android and different handsets ranging from 16MB - 32MB. I think I see 24MB the most common. So it's very likely that you are simply running out of memory for your image. Check out this post to see what your heap size is: https://stackoverflow.com/a/9428660/1448071.
Edit: There does not appear to be a good way to increase VM heap size for Android. There is a VMRuntime.getRuntime() function with a setMinimumHeapSize function described here Android: how to increase heap size at runtime?. But it appears to be getting deprecated. I would recommend that you split up your sprite.
Upvotes: 1
Reputation: 6414
you need to increase the VM heap size. i'd love to grab links for you, but i guess this is the best i can do atm - Increase heap size in Java
Upvotes: 0