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
Related
Hi There:) I am trying to create Image Gallery in Android, I am trying to load Thumbnails from HD images(more than 1000) from local device.
Glide.with(context)
.load(Uri.fromFile(new File(MyPhotoList.get(position).getPath()))).override(110,110)/*.thumbnail(0.1f)*/
.placeholder(R.color.colorAccent).into(holder.image);
But on scroll, RecycleView stucks and load image after few sec.(CPU: 70-80%, 180 MB, It consumes.)
(Test Device config. Deca-core 2.3 GHz, 4 Gb RAM).
Could you please suggest me, how to make smooth scrolling for image gallery.
I think this is normal behavior. On every another app launch (after the first one) glide will load those photos from its cache so it will be much smoothier.
To explain this just calculate, the phone needs to load e.g 20 photos those size together is about ~200/300 MB. Now take device's flash memory read speed. Most of devices may have about speed rate up to ~120 mb/s, so it means it may load those photos in few seconds.
Take a quick try with stock Gallery app on your phone. Open this and swipe down and see images and videos loading and compare with your app speed. Then you will know how big is difference againist those apps if any.
So, I've been researching on bitmap scaling using the bitmap factory.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I'm doing so because the application I'm working on requires a gallery that allows users to submit their photos to be added to the gallery. These photos will then be read from a URL.
My theoretical problem is this: Considering the android devices can have as low as 16MB of memory, even scaling down the images is only delaying the inevitable unless only handling a single image. Whereas in my case, the amount of images that will be loaded could be hundreds. Meaning that even if they're scaled down, eventually one will reach that limit.
My only idea thus far are to load one image at a time, which is not preferable since users will have to wait between photo transitions.
That being said, is there anyone who has experience developing applications on android that handle 100's of images? If so, is there any theory you could share on handling all these images fluidly? It can obviously be done, as there are gallery applications available. I am just unsure how they accomplished it given the restraints.
Please note this is not a request on how to use the bitmap factory to scale images, as that question has been answered many times.
Rather a request on handling data amounts you know will exceed limitations.
The gallary apps should not be storing all thousands of images in memory. Use the Viewholder pattern such that the image views displayed will get recycled (this is forced upon you if you use RecyclerView). On backend use an image cache and keep a limit on it size.
See e.g. What is the benefit of ViewHolder? and How to release memory of bitmap using imageloader in android?
The Android gallary app source may be a good reference: https://android.googlesource.com/platform/packages/apps/Gallery/+/android-5.1.1_r18/src/com/android/camera
I am into developing an android app which fetches images from server. A single activity downloads more than 10 images from the server. So, what should be the size of images(in bytes) so that the app runs smoothly and swiftly?
It is not the size of images that really matters..its the resolution of the image that really matters. When you try to take that image to a bitmap variable, the memory is consumed to represent each pixel of your image. Since you are working in a client server scenario, the size will become a problem when it comes to download and store the image.
If you don't need to zoom the image in your application, it is better to use image with standard resolution that matches screen size.
Its better for you to use some image manager libraries for these kind of image loading purpose, so that they will manage the memory issues to an extend. Check this post.
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 a simple app that displays a series of images and infomation about those images. I've set it up so that when a user touches an image, a new activity is launched and they see more pictures and a longer text description about that image. On that screen, I've also implemented the basic gallery widget that they have here in the Hello Gallery Tutorial.
My problem is that even though I'm drawing on images from the res directory (I've thrown everything in drawable-mdpi thinking that there shouldn't be a huge deal), not all of the images on the gallery portion will load. And I haven't been able to reproduce it 100%, but it seems like the more I play with my phone with this app running (lock screen, unlock screen, go to one image, go back, go to another one, hit home, etc), the more likely any picture that I've got loaded up locally display blank image placeholders, gallery or not (the text comes up fine though).
I'm using a series of imagebuttons, imageviews, and gallery widgets. Play with it enough and eventually they all come as blank, but killing everything through AdvancedTaskKiller brings it back.
Sometimes pictures in my image galleries will also be blank when I first launch my app. That's really weird. I have it set so that the layoutparams are 300 by 200 and I've pulled pictures all over the place to populate my gallery. They should just all scale differently, not fail to load entirely though.
Anybody have any ideas on these?
Try Slow Adapter for the Gallery.
I recommend adopting 1,2,3
It is always hard to work with images. You have to be very careful with recycling memory that your images already used otherwise you could get into different kind of troubles.
Always try to use a good Image loading library that commonly being used by Android developers.
Most commonly used library is https://github.com/nostra13/Android-Universal-Image-Loader
It will optimise your loading.