I am developing an android app which needs to load a big image quickly. Using Instagram on Android I have noticed a feature they have that I cannot figure out how it works. Instagram users have a feed which displays usually a scroll list with a bunch of small thumbnails:
When you click an thumbnail image you get sent to another page(assuming fragment) that shows a bigger version of the image which appears instantly (to the human eye it looks instant)
You can scroll through all these thumbnails which means a lot of thumbnails display very quickly which I can understand because the images are small and sending over the network would be relatively quick. The problem I am understanding is how the larger images appear so quickly!? When the app downloaded the thumbnails are the larger images downloaded at the same time (I do not think this is the case because it would be such a waste of network traffic since most users on't click on every thumbnail? What technique is being used to have such fast response times for large images? I thought it maybe because of cache, but it happens when I click a picture I have never seen before.I is so fast it looks like it even is not hitting the network.
How clicking on a thumbnail image produces a a larger image so quickly?
Uses faster CDN networks to fetch images
Uses Fresco for image loading which implements progressive image loading
Uses RecyclerView, image loading is triggered when ever you stop scrolling.
Probably uses webp and jpg image formats
Images are cached for later use
I am new to Android and I having troubles setting a dynamic background just like Tumblr login UI,
The link below is where I got some help.
Set Animated .GIF As Background Android
But it only works when I load small-size animation, or I have to drop lots of frames of a GIF animation which leads to incoherence.
If I load all the frames which will cause OutOfMemoryError, I don't think it's the right way.
Is tumblr uses GIF animation or it's actually a short video?
I know that Twitter converts all GIFs to MP4. Video compression is far better than GIFs leading to smoother playback and reduced bandwidth and happy users :) Is using MP4s an option?
More on the subject here.
Not sure how long your animation is, or how high res its frames are, but you probably need to look at loading the image frames in scaled down form into memory. The Android docs give a very coherent explanation of how to do this here (basically, you first find the res of the bitmap, then load a scaled down version of it appropriate to the device's screen resolution). It may also be that the animation is too long, and you need to look at forcing bitmaps to recycle (using bitmap.recycle()) once displayed.
My app should show a bunch of animated images (within a list or grid, ~10-20 images on a screen depending on the screen size). Each of these images can contain a lot of frames (up to 150). Actually these images are gifs initially. I get them as encoded mp4 files (to reduce the data size transferred through the network) and decode them on a device. For decoding I use android.media.MediaMetadataRetriever (it doesn't work well on Samsung devices) and I do it the following way: when I show the current frame I put a new decoding task - actually a task to get the next frame - to a priority queue. Priority depends on the time to which I need to get the next frame. If task "expires" (isn't processed by workers before expected time) I just put to a queue next task and etc. But my algorithm doesn't work well - animations are very slow and buggy (I don't also exclude that my implementation can have some bugs)..
So, here are the questions:
1) Are there any other possibly better ways to decode mp4?
2) Could someone please give me and advice which algorithm I should use to effectively decode mp4 files, so there weren't any animation lags?
3) I can't use simple AnimationDrawable because of out of memory errors, so how can I effectively manage frames cache?
Thanks!
I have a problem: (I wouldn't be here otherwise ;)
I am creating an app that has a feature for displaying "3D" models. This part is really a collection of images taken from many angles and allows the user to "rotate" the "model".
This idea is working fine, but the problem lie in the loading of the images.
I have found that there are two ways:
Load all the images into memory, and then simply switch them for the correct angle.
Load the images as we need them - we can load a few ahead of time.
However these have problems:
If I was lucky, the images would fit into memory, but they don't. They are about 1.5-2MB each and there are about 75-100 images per model. This brings the total size to about 115MB at the minimum.
If I was lucky, the image would load quicker than the user could "rotate", but they don't. The user can easily switch to an angle that is not loaded yet, resulting in a black screen for a few seconds.
I have created a loader that allows me to simply add the images that I need to a stack and the loader will then one-by-one load the images. This works fine if the user scrolls fairly slowly. My loader takes care of releasing memory when it is finished, so no matter how many images I load, the app usually won't crash as long as I specify the max images to store in memory. My loader can load the images very quickly, but there is still a few milliseconds (~250ms) for it to load the large image into memory.
Of course, the loader is on a different thread, and the loading in no way hinders UI response. That is why if the user swipes back and forth quickly, no image will actually display, as the loading and unloading are all working at the same time to result in no images :)
So, my problem: How do I provide a smooth and user-pleasing rotation of the images without loading all the images into memory?
Don't load (or store) resolution you don't need. If your user needs to zoom, an out-of-memory binary image pyramid is a cheap way to let you load only the level of zoom necessary. If your user needs to pan through an image larger than your display area, you can break your large image into smaller tiles, and only load the ones you need.
If you want to get fancy, you can write a UI-aware cache manager to preemptively load tiles you think you might need soon, and mark tiles you're pretty sure you won't need soon for preemption.
Better compression can fit more image data into memory, and speed up load time. So, pay attention to individual image compression, and don't load image quality you don't need, either.
As an extraordinary measure: since images from slightly different angles are similar to each other, you may be able to save time and space by representing the difference, instead -- look up lightfield compression. You will still need to convert from compressed form to a particular bitmap you can draw, but if the compression allows the dataset to remain in memory, you could potentially gain a lot of speed.
If you can't fit your compressed dataset into memory, there's a good chance the user will be able to swipe back and forth quickly enough to defeat your cache. So, if smoothness is your main goal, you could try for a "UI solution" by restricting the rotation rate (or the per-swipe rotation range?) to something your data loader can follow.
My only suggestion is for loading them efficiently. I assume that you are using techniques described here
If the images are of higher resolution than the screen you can calculate the sample size of the image you want to render then you can load an image that fits your screen rather than the full size image which will use much less memory. If you are already doing that then to me it seems like how you are doing it efficiently already. Perhaps you could show the user some kind of placeholder graphic while an image is loading so they won't just have blank space.
Thanks for the answers. I laughed at myself and then went to bed after reading the answers.
Let me share how I resolved this problem - it uses some pieces of the answers:
I was trying to cache the large images in memory - this is unnecessary, why not store a lower res version and then load the hi res when the user stops scrolling? Then the user can scroll as fast as he likes and there will always be images in memory to quickly paint. When the user stops/slows scrolling, we load the hi res image.
Because he will be scrolling fast, he won't be able to see the lower res' lower quality.
And, as there will only be one hi res to load, the ~250ms delay is hardly noticeable.
This really combines the best of both cases. And I can use the Android's methods for loading a lower res version of the Bitmap.
I have an application, where it downloads a no of images (no of images are not fixed) from server(internet).
at first i tried only one image it took 2min to display.
Now i am trying to load 5 images so it takes 10 to 15 mins to display, which shouldnt be like this.
What can I do so that it take a small duration of time as a normal application takes.
Thank you
Use AsyncTask - It will allow you to display images as and when they are downloaded. No need to wait for displaying till all the images are there !
You can use Lazy List that will cache the images in Cache memory and let you to load images very fast.
Check this Link Lazy List sample.......