package com.ideabag.playtunes.util;
import java.lang.ref.WeakReference;
import com.ideabag.playtunes.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String path;
int mImageWidth;
//private Context mContext;
public BitmapWorkerTask( ImageView imageView, int destWidthPx ) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
mImageWidth = destWidthPx;
//Context mContext = imageView.getContext();
//mContext.getResources().getDisplayMetrics().density
// TODO:
// When this is first called, the width is 0
// Creates bad album art on initial load
//mContext = imageView.getContext();
}
public BitmapWorkerTask( ImageView imageView ) {
this( imageView, 0 );
}
// Decode image in background.
@Override
protected Bitmap doInBackground(String... paths) {
final BitmapFactory.Options options = new BitmapFactory.Options();
path = paths[0];
// First decode with inJustDecodeBounds=true to check dimensions
Bitmap bmp = null;
if ( !isCancelled() ) {
if ( mImageWidth > 0 ) {
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile( path, options );
int sample = calculateInSampleSize( options, mImageWidth, mImageWidth );
//android.util.Log.i( "BitmapWorkerTask", "Sample: " + sample + " desired width: " + mImageWidth );
// Calculate inSampleSize
options.inSampleSize = sample;
// Decode bitmap with inSampleSize set
}
options.inJustDecodeBounds = false;
if ( !isCancelled() ) {
try {
bmp = BitmapFactory.decodeFile( path, options );
} catch( Throwable t ) {
t.printStackTrace();
}
}
}
return bmp;
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute( Bitmap bitmap ) {
if ( isCancelled() ) {
bitmap = null;
}
if ( imageViewReference != null && bitmap != null ) {
final ImageView imageView = imageViewReference.get();
if ( imageView != null ) {
AlphaAnimation fadeIn = ( AlphaAnimation ) AnimationUtils.loadAnimation( imageView.getContext(), R.anim.fadein );
imageView.setImageBitmap( bitmap );
imageView.startAnimation( fadeIn );
}
}
}
private static BitmapWorkerTask getBitmapWorkerTask( ImageView imageView ) {
if ( imageView != null ) {
final Drawable drawable = imageView.getDrawable();
if ( drawable instanceof AsyncDrawable ) {
final AsyncDrawable asyncDrawable = ( AsyncDrawable ) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
public static boolean cancelPotentialWork( String data, ImageView imageView ) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask( imageView );
if ( bitmapWorkerTask != null ) {
final String bitmapData = bitmapWorkerTask.path;
// If bitmapData is not yet set or it differs from the new data
if ( bitmapData == null || bitmapData != data ) {
// Cancel previous task
bitmapWorkerTask.cancel( true );
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
// TODO:
// Rather than scaling by factors of 2, scale by factors of the device's screen density
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
/*
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
*/
/*
public void loadBitmap(int resId, ImageView imageView) {
if (cancelPotentialWork(resId, imageView)) {
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
imageView.setImageDrawable(asyncDrawable);
task.execute(resId);
}
}
*/
}