Fastest way to load thumbnails from camera - android

I'm trying to implement a gallery and I have a GridView that displays all the images (thumbnail) in the camera folder. To get the thumbnails, I basically get their IDs using:
final String[] PROJECTION =
new String[] {MediaStore.Images.Media._ID};
Cursor pictureCursor = getActivity().getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
PROJECTION, null, null, MediaStore.Images.Media._ID);
ArrayList<Integer> ids = new ArrayList<Integer>();
int idIndex = pictureCursor.getColumnIndex(MediaStore.Images.Media._ID);
while (pictureCursor.moveToNext()) {
ids.add(pictureCursor.getInt(idIndex));
}
And to read the thumbnails, I'm using
Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(content_resolver, ids.get(position), MediaStore.Images.Thumbnails.MICRO_KIND, null);
on an AsyncTask as specified in http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
But as I'm comparing the load times between my app vs. Android's native gallery app, I'm seeing that the gallery app loads thumbnails MUCH faster than my app, all the while having better image quality than my Thumbnails.MICRO_KIND. Is there a faster way to load thumbnails than to use MediaStore.Images.Thumbnails.getThumbnail() function? because obviously the gallery app loads thumbnails much faster.
NOTE: this is when the app is initially opened, before cache comes into play. After my cache stores images, then load time is near instant. So, not a cache problem.
EDIT:
I thought I should clarify. It's not that my UI is getting locked or my app is slow, since I'm already using an AsyncTask to read my images off the UI thread. What I'm asking is if the function MediaStore.Images.Thumbnails.getThumbnail() is the fastest way to load thumbnails already stored on the phone?

Use Universal Image Loader it takes care of your issues which most likely stems from you loading the wrong sizes and/or not caching the results.

Related

How to reduce the time for video thumbnail

So I am displaying video files from specific folder when the folder is selected but in the video list I am showing file name with the video thumbnail and that's where the problem starts i am using this way to get the thumb
Bitmap bmThumbnail = ThumbnailUtils.
extractThumbnail(ThumbnailUtils.createVideoThumbnail(info.getFilename(),
MediaStore.Video.Thumbnails.MINI_KIND), 60, 60);
if(bmThumbnail != null) {
imageView.setImageBitmap(bmThumbnail);}
and even if I don't set the bitmap or not the process is taking way too much time to open the new fragment whereas just displaying the name is smooth if I call the following bitmap it takes around 6-7 sec to display the list. The following thing are happening in the adapter as I test the app in adapter then recycler view
so I would like to know what is the best way to do it .
For using image loader i need the url which is not there as i am getting the album art using the file url but it will not produce the album art url directly.
Dealing with images and videos like that takes time. Particularly when dealing with a large group of them. It's unlikely you can speed up the operation but you can make it so your application doesn't have to wait for it by sending it to the background. I recommend Kotlin coroutines if you are up for converting to Kotlin. Otherwise I recommend making a thumbnail work manager
public class VideoThumbnailWorker extends Worker {
}

Android OutOfMemory

What is my Problem (KISS)?
After showing the 3rd Image in Detail my App crashes cause OutOfMemory
Background information about my App:
I made an offline Supermarket. All products are shown in a ListView.
All Images I use are stored as String (Uri from every Image) in a sqlite Database by SugarORM.
The ListView element got a ArrayAdapter where the Information for each Item in the ListView is set.
Like this:
ImageView imageView = (ImageView) rowView.findViewById(R.id.productimage);
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
imageView.setImageURI(productList.get(position).getPictureUri());
handler.removeCallbacks(this);
}
});
My Intention was, to load the Images in the Background to Click on it, even before the Image is loaded (But it did'nt work for me :/ The Image is Shown, but I cant click on any other View Element while Loading the Image).
The "getPictureUri" gets the URI from the Picture that the Admin has choosen for the product with the following Code:
Intent pickPhoto = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto,1);
AndroidManifest.xml
android:hardwareAccelerated="false"
android:largeHeap="true"
I extend only from "AppCompatActivity" (Needed for Toolbar). Meaning of this: I don't use "Activity" even once.
Could anyone give me a good advice, how to clear the cached Images (I think this might be the Problem) and besides, maybe one of you got the Time to help me with my "Image Async Loading while you are able to move freely in your app" Problem.
Using setImageUri() is rather intensive on memory, especially when trying to load large bitmaps from a local resource. Instead, use tried and true solutions like Picasso or Glide for any/all image loading tasks. The libraries will work offline, can definitely load images from URIs pointing to a local resource and would most likely solve all your memory issues with image loading.

Android doesn't save Thumbnails in Cache

I notice a different behavior in android management of thumbnails.
This is my code:
String[] sProjection = new String[]{MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DISPLAY_NAME,MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID};
Cursor oCur = oActivity.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
sProjection,"",null,MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
do{
...
Bitmap oBmp = MediaStore.Images.Thumbnails.getThumbnail(oActivity.getContentResolver(),bmpID,
MediaStore.Images.Thumbnails.MICRO_KIND,null);
...
}while (oCur.moveToNext());
And then after loading all thumbnails, I make some elaborations with some of them.
With my mobile (Android 4.1.2) after loading all thumbnails for the first time (for example with new photos or after cleaning cache in Media Storage), "do while" loop is very quick because all the tumbanails are already created and saved in cache.
With another one (same Android version) every time you execute the loop there are no improvements of velocity, because it doesn't save them but it recalculate them all (viewed with the messages in Eclipse LogCat).
Why do this happen?! Is there a way to solve this issue and to force Android save thumbnails in cache memory?
Thanks a lot for the help, any suggestion is greatly appreciated.

How much thumbnails can I store until I run out of memory?

For my app, I'm currently reading through ALL the image (JPEG) files stored on the phone and saving their ID, and thumbnails (NOT the original Bitmap) onto a HashMap.
Code:
final String[] PROJECTION =
new String[] {MediaStore.Images.Media._ID};
Cursor pictureCursor = getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
PROJECTION, null, null, MediaStore.Images.Media._ID);
HashMap<Integer,Bitmap> thumbnails = new HashMap<Integer,Bitmap>();
int id;
int id_index = pictureCursor.getColumnIndex(MediaStore.Images.Media._ID);
int THUMBNAIL_TYPE = MediaStore.Images.Thumbnails.MICRO_KIND;
ContentResolver content_resolver = context.getContentResolver();
while (pictureCursor.moveToNext()) {
id = pictureCursor.getInt(id_index);
Bitmap thumbnail = MediaStore.Images.Thumbnails.getThumbnail(content_resolver, id, THUMBNAIL_TYPE, null);
thumbnails.put(id, thumbnail);
}
I currently have 200 images on my phone, and it works fine now. But I'm worried that at certain point, the app will run out of memory and crash.
Is running out of memory something I need to take into consideration? Or are thumbnails small enough that practically speaking, the app won't run out of memory?
EDIT
If I should worry about running out of memory, what's the best way if I want something like Android's native gallery app, which doesn't seem to have a "load more images" button but rather an endless stream of images?
Thanks
MICRO_KIND thumbnails are not very big, and you will very likely be fine. But if you are putting your app out there, you will absolutely find people with memory problems. It will be due to either an insane number of photos, a mediocre device, or some combination of the two.
You can calculate the memory use of your thumbnails. It shouldn't be too hard to create one or two thumbnails, and find out how big they are. Then you can calculate available heap (Native heap on pre 3.0, Dalvik heap after 3.0) and get an idea of how many you can make.
You can get a count of the items in your cursor at this point in your code:
Cursor pictureCursor = getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
PROJECTION, null, null, MediaStore.Images.Media._ID);
int numberOfImages = pictureCursor.getCount()
HashMap thumbnails = new HashMap();
and then know if you have plenty of room or not. If you are limited in space, you will need to make a design decision--either warn the user that its not going to work, or only look at the first "x" images, then free those up and load another set at the users request.
It depends on heap size and how memory intensive your app is.
I suggest you have a look at the video in the link
http://www.youtube.com/watch?v=_CruQY55HOk.
If you run into memory leaks you can use MAT Analyzer to find and fix the problem.
You need to reduce memory usage and if heap sizes grows and your app requires space in heap, the gc kicks in to free memory. But if there is not enough space you are likely to run into memory leaks.
http://developer.android.com/training/articles/perf-tips.html

not accessing images from cache properly in listview

I am downloading images from server into the ListView and storing it into SD Card.
And when next time listview appears i am accessing it from SD card only using Async method, i
use this approch so that every thing user does not need to access server.
But when all the images are being loaded into listview from SD Card and if i scroll it
pretty fast then every time it tries to access it from the SD Card only rather then from Caches i guess.
I was facing the same problem when images are being downloaded from server also , and thats why i thought to store it into SD Card. but i am facing the same issue.
here is my code ListImageDownloader . In that there is a function called downloadBitmap(String) and i have created another function named downloadSDBitmap(String) whose code is as follows
Bitmap downloadSDBitmap(String urlId) {
Bitmap bitmap = null;
File file = new File(
fileLoc +"/"+ urlId+".png");
if(file.exists()){
Log.d("PATH" , file.getAbsolutePath());
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}
return bitmap;
}
apart from this the whole caching code and all are same. so can anyone help me how can i improve it as in a Gtalk android application when i scroll fast it loads the images only once after that if i scroll fast the images remains as it is and doesnt fetch from network
Update
these are my parameters
final static int MAX_ENTRIES = 150;
private static final int HARD_CACHE_CAPACITY =50;
private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds
Caching fundamentally relies on available memory. If there is memory left for your application you will need to implement a good solution that caches your bitmaps.
In the past was SoftReference/WeakReference a popular method to cache bitmaps (I did try it a year ago, you can read about my question about this here). But in later APIs of Android the garbage collector has become more aggressive collecting those and therefore they are not no longer recommended.
Now it is recommended to use an LRU cache. There is an example available on the Android developers website.

Categories

Resources