mercredi 18 juin 2014

createVideoThumbnail loading images slowly. How to improve performance?


Vote count:

0




I have two GridViews that are populated with the VideoThumbnailAdapter below and another very similar adapter ImageThumbnailAdapter -- both of which call on the same AsyncThumbnailLoader with a different variable: either THREAD_VIDEO or THREAD_IMAGE.


My approach to loading thumbnails for images is from their URI using the getThumbnail(Uri) function called from doInBackground(Object...params) in AsyncThumbnailLoader . These image thumbnails are loading quite quickly; I believe this is because the Bitmap is being treated carefully in the getThumbnail(URI) function (however I am not certain of this).


For video thumbnails, I am using ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MICRO_KIND) to obtain a Bitmap which is directly being passed on to the ImageView for the Adapter to use.


The problem is that the GridView is taking a lot of time to populate the thumbnails, even when the number of items is as little as 16. This is especially true for the video thumbnails, which take almost a second each to load. I have also noticed that the first four or five thumbnails load almost instantly (for images and/or video), but loading slows down after this. I am not sure where the poor performance can be improved. Optimizing the videoThumbnail bitmaps? Recycling bitmaps? Getting the videoThumbnail Uri manually? Something to do with cache? Can I clear the memory so the rest of the thumbnails load as fast as the first few? Downsampling?


I considered using http://ift.tt/Ucbphw but I have no idea where to start. Guidance would be incredibly appreciated! Thank you for taking the time.


VideoThumbnailAdapter used to populate GridView:



public class VideoThumbnailAdapter extends BaseAdapter {
private Context mContext;
/* Methods: constructor, getCount(), getItem(int), getItemId(int) */

public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
imageView = new ImageView(mContext);
new AsyncThumbnailLoader(imageView, true, position, THREAD_VIDEO).execute();
return imageView;
}
}


The AysncTask getting the thumbnails for the Video/ImageThumbnailAdapter:



private class AsyncThumbnailLoader extends AsyncTask<Object, Void, Bitmap> {

boolean enable_animation = false;
private ImageView imageView;
int position;
String videoPath;
int picture_video_audio;

public AsyncThumbnailLoader(ImageView imageView, Boolean animation, int position, int picture_video_audio)
{ /* Constructor assignments to local variables */ }

@Override
protected void onPreExecute() {
imageView.setLayoutParams(new GridView.LayoutParams(
THUMBNAIL_SIZE, THUMBNAIL_SIZE));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(2, 2, 2, 2);

if (picture_video_audio == THREAD_VIDEO) {
Uri myUri = Uri.parse(videoURIlist[position]);
videoPath = getRealPathFromURI(getBaseContext(), myUri);
if (videoPath.length() == 0) {
videoPath = myUri.getPath();
}
}

@Override
protected Bitmap doInBackground(Object... params) {
if (picture_video_audio == THREAD_VIDEO) {
return ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MICRO_KIND);
} else { // if (picture_video_audio == THREAD_IMAGE)
try {
return getThumbnail(Uri.parse(imageURIlist[position]));
} catch (Exception e) {
return null; // TODO Put placeholder image thumbnail
}
}
return null;
}

@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}


The getThumbnail(Uri) function:



public Bitmap getThumbnail(Uri uri) throws FileNotFoundException,
IOException {
InputStream input = this.getContentResolver().openInputStream(uri);

BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither = true;// optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
if ((onlyBoundsOptions.outWidth == -1)
|| (onlyBoundsOptions.outHeight == -1))
return null;

int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight
: onlyBoundsOptions.outWidth;

double ratio = (originalSize > THUMBNAIL_SIZE) ? (originalSize / THUMBNAIL_SIZE)
: 1.0;

BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither = true;// optional
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional
input = this.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}


asked 13 secs ago






Aucun commentaire:

Enregistrer un commentaire