Say I need to make several full-screen animation that would consist of about 500 frames each.
Animation should be playing at a reasonable speed - supposedly not less, then 20fps - and pictures should be of a reasonable quality, not overly compressed.
What method do you think should I use?
So far I tried:
1. storing each frame as a compressed JPEG
2. before animation starts, loading each frame into a byteArray
3. as the animation plays, decode corresponding byteArray into a bitmap
and draw it on a surface view.
Problem - speed is too low, usually about 5-10 FPS.
I have thought of two other options.
turning all animations into one movie file... but I guess there might be problems with starting, pausing and seeking to the exactly right frame... what do you think?
another option I thought about was using OPENGL ( while I never worked with it before ), to play animation frame by frame. What do you think, would opengl be able to handle it?
Thanks!
edit, i managed to peek into talkingtom, and found that it contains about 20megs of well compressed JPEGs, like this.
You could handle it in a couple of different ways.
It sounds like decoding is your bottleneck. You could try making all the 3 steps including the decoding before playing the animation, so you will just have to draw the already-converted bitmaps.
OpenGL is definitely up to the task in the sense that it will probably never be your bottleneck. But as said above, the drawing does not seem to be the problem.
Animating on the device. In case you are animating geometric objects or pixmaps and the animation has a common background you could reuse, separate the animation into "actors" and move them around - this will require much less data.
EDIT : Complex animations on mobile devices are rarely full-screen movies or series of images - the amount of (redundant) data would be overwhelming (as you have noticed already). They are animated 2D and 3D models. For 3D it is advisable to use OpenGL, for 2D, common canvas drawing may be enough. To make it even more efficient, you could split the model into separate parts and animate them separately (would look similar to SouthPark animations). You can combine this with using spritesheets (like separate small movie strips) to animate separate parts. This would give you much more flexibility while still using less data than a compressed movie.
I really think you need to turn it into a movie file - that will give you some appropriate compression and android can do all the work with the media player. I believe getting to the right frame is fairly easy but you may have to use lower compression on the video stream to make this work.
Maybe using universal tween engine can fix your performance problem.
Related
I want to apply little tricky fluid ink animation as same as the below image:
I want to achieve using the basic classes only like applying scale, translate etc. I don't want to go with 2D or 3D. As I have checked some of the links they are suggesting frame animation but It doesn't have smooth transition.
Kindly suggest best way to achieve this animation.
Thanks,
"I don't want to go with 2D or 3D."
Well.. I don't know about you but those are the only options until we have 4D screens and mindsets.
But I guess you mean using 2D images or 3D models.
Unless you want to procedurally generate that (which can be quite a pain) I'd suggest using a spritesheet, there may be better ways to do this but I think a spritesheet on 30fps might be the easiest + fluid way to do this, increase FPS to increase fluidness (until the max of androids 60 fps screens)
Basically:
Create a (example) 256x128 sprite, and "manually" animate the sphere to the other side of the image, saving each "frame" and either create 1 big texture with all the frames (most efficient) or save each frame independently (lower on RAM if you manage it well, but it'll be hard to get 60 fps with this due to loading times)
You can check the recently announced Lottie library (by Airbnb).
It is a library for Android that parses Adobe After Effects animations exported as json with Bodymovin (related project) and renders them natively on Android devices.
I am trying to write a libgdx livewallpaper (OpenGL ES 2.0) which will display a unique background image (non splittable into sprites).
I want to target tablets, so I need to somehow be able to display at least 1280x800 background image on top of which a lot more action will also happen, so I need it to render as fast as possible.
Now I have only basic knowledge both about libgdx and about opengl es, so I do not know what is the best way to approach this.
By googling I found some options:
split texture into smaller textures. It seems like GL_MAX_TEXTURE_SIZE on most devices is at least 1024x1024, but I do not want to hit max, so maybe I can use 512x512, but wouldn't that mean drawing a lot of tiles, rebinding many textures on every frame => low performance?
libgdx has GraphicsTileMaps which seems to be the tool to automate drawing tiles. But it also has support for many features (mapping info to tiles) that I do not need, maybe it would be better to use splitting by hand?
Again, the main point here is performance for me - because drawing background is expected to be the most basic thing, more animation will be on top of it!
And with tablet screen growing in size I expect soon I'll need to be able to comfortably render even bigger image sizes :)
Any advice is greatly appreciated! :)
Many tablets (and some celphones) support 2048 textures. Drawing it in one piece will be the fastest option. If you still need to be 100% sure, you can divide your background into 2 pieces whenever GL_MAX_TEXTURE happens to be smaller (640x400).
'Future' tables will surely support bigger textures, so don't worry so much about it.
For the actual drawing just create a libgdx mesh which uses VBOs whenever possible! ;)
Two things you dindn't mention will be very important to the performance. The texture filter (GL_NEAREST is the ugliest if you don't do a pixel perfect mapping, but the fastest), and the texture format (RGBA_8888 would be the best and slowest, you can downgrade it until it suits your needs - At least you can remove alpha, can't you?).
You can also research on compressed formats which will reduce the fillrate considerably!
I suggest you start coding something, and then tune the performance up. This particular problem you have is not that hard to optimize later.
After a lot of searching and days of experiments I haven't found a straight-forward solution.
I'm developing an app that user will interact with a pet on the screen and i want to let him save it as video.
Is there any "simple" way to capture the screen of the app itself?
I found a workaround (to save some bitmaps every second and then pass them to an encoder) but it seems too heavy. I will happy even with a framerate of 15fps
It seems to be possible, i.e. there is a similar app that does this, its called "Talking Tom"
It really depends on the way you implement your "pet view". Are you drawing on a Canvas? OpenGl ES? Normal Android view hierarchy?
Anyway, there is no magical "recordScreenToVideo()" like one of the comments said.
You need to:
Obtain bitmaps representing your "frames".
This depends on how you implement your view. If you draw yourself (Canvas or OpenGL), then save your raw pixel buffers as frames.
If you use the normal view hierarchy, subclass Android's onDraw and save the "frames" that you get on the canvas. The frequency of the system's call to onDraw will be no less than the actual "framerate" of the screen. If needed, duplicate frames afterwards to supply a 15fps video.
Encode your frames. Seems like you already have a mechanism to do that, you just need it to be more efficient.
Ways you can optimize encoding:
Cache your bitmaps (frames) and encode afterwards. This will work
only if your expected video will be relatively short, otherwise
you'll get out of storage.
Record only at the framerate that your app actually generates (depending on the way you draw) and use an encoder parameter to generate a 15fps video (without actually supplying 15 frames per second).
Adjust quality settings to current device. Can be done by performing a hidden CPU cycle test on app startup and defining some thresholds.
Encode only the most relevant portion of the screen.
Again, really depending on the way you implement - if you can save some "history data", and then convert that to frames without having to do it in real time, that would be best.
For example, "move", "smile", "change color" - or whatever your business logic is, since you didn't elaborate on that. Your "generate movie" function will animate this history data as a frame sequence (without drawing to the screen) and then encode.
Hope that helps
So we know about this two ways of implementing animations on Android
I couldn't find any performance difference if there are any..
I am aware that frames will make apk file bigger (picture for each frame), and that with tween you need/can precisely to define animation, but which way of animating is from memory/cpu consumption side more efficient? Any clue?
Thanks
I'm working with my friend on our first Android game. Basic idea is that every frame of the game the whole surface is redrawn (1 large bitmap) in 2 steps:
Background with some static image (PNG) wipes out previous frame
Then it is sprinkled all over with large number of particles which produces effect of soapy bubbles where there's a pool of about 20 bitmaps which randomly gets picked to produce illusion that all bubbles (between 200 - 300) are all different. Bubbles positions updated on each frame (~50ms) producing effect of moving bubbles.
The math engine is in C (JNI) and currently all drawing is done using android.graphics package very similar (since that was the example I was using) to Lunar Lander.
It works but animation is somewhat jerky and I can feel by temperature of my phone that it is very busy. Will we benefit from switching to OpenGL? And as a bonus question: what would be a good way to optimize the drawing mechanism (Lunar Lander like) we have now?
Now I've started to work with OpenGL ES, I would also use it for 2D graphics. This way is the most flexible and it's extremely fast (look at this example code. It's about 2D rendering, and there you can see the power of OpenGL.
It's not the easiest thing to start with, but there are some good tutorials out there - for example, this is a very good one.
Don't redraw the entire screen each time. That's what causes your low framerate. Use the invalidate method to mark the areas that have changed each frame.