Im, использующий DisplayingBitmap.zip, загруженный с сайта разработчиков android для загрузки изображений асинхронно в изображение. Im получает base64 строки из webservice. поэтому изменил код, чтобы преобразовать base64 в bitmap в ImageFetcher.class из (DisplayingBitmaps) вместо загрузки изображения с URL-адреса.ImageView, показывающий черный/белый фон для прозрачного base64 string image
ПРИМЕЧАНИЕ: Im получение gif изображений в виде base64 строки.
Преобразование в растровое изображение base64
public Bitmap convertBase64ToImage(String mBase64String) {
Bitmap bitmap = null;
try {
String imageDataBytes = mBase64String.substring(mBase64String.indexOf(",") + 1);
InputStream stream = new ByteArrayInputStream(Base64.decode(imageDataBytes.getBytes(), Base64.DEFAULT));
bitmap = BitmapFactory.decodeStream(stream);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
Преобразование base64 растрового изображения в файл Симметричного для получения декодированного уменьшенное растрового изображения с использованием метода processBitmap в ImageFetcher.class (DisplayingBitmaps):
/**
* The main process method, which will be called by the ImageWorker in the AsyncTask background
* thread.
*
* @param data The data to load the bitmap, in this case, a regular http URL
* @return The downloaded and resized bitmap
*/
private Bitmap processBitmap(String data, String imageID) {
if (BuildConfig.DEBUG) {
PrintLog.error(TAG, "processBitmap --- imageID " + imageID);
}
Bitmap bitmap = null;
bitmap = convertBase64ToImage(data);
if (bitmap != null) {
File f = null;
try {
//create a file to write bitmap data
f = new File(mContext.getFilesDir(), imageID);
f.createNewFile();
//Convert bitmap to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100/*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
bitmap = decodeSampledBitmapFromFile(f.getAbsolutePath(), mImageWidth, mImageHeight, getImageCache());
}
return bitmap;
}
@Override
protected Bitmap processBitmap(Object data, String imageID) {
return processBitmap(String.valueOf(data), imageID);
}
decodeSampledBitmapFromFile метод из ImageResizer.class
public static Bitmap decodeSampledBitmapFromFile(String filename, int reqWidth, int reqHeight, ImageCache cache) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// If we're running on Honeycomb or newer, try to use inBitmap
if (DeviceUtils.hasHoneycomb()) {
addInBitmapOptions(options, cache);
}
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
Реализация ImageFetcher.class (DisplayingBitmaps.zip) в моем классе
private static final String IMAGE_CACHE_DIR = "clubsCategoryIcons";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImageCache.ImageCacheParams cacheParams = new ImageCache.ImageCacheParams(getActivity(), IMAGE_CACHE_DIR);
cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 10% of app memory
// The ImageFetcher takes care of loading images into our ImageView children asynchronously
mImageFetcher = new ImageFetcher(getActivity(), getResources().getDimensionPixelSize(R.dimen.image_icon_size));
mImageFetcher.setLoadingImage(R.drawable.settings_clubs);
mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);
}
передавая этот объект mImageFetcher в класс адаптера для загрузки изображений в асинхронном режиме для каждого элемента.
ClubsCategoryAdapter clubsAdapter = new ClubsCategoryAdapter(getActivity(), new ArrayList<ClubsCategoryParser.ClubsCategory>(), mImageFetcher);
recyclerView.setAdapter(clubsAdapter);
ClubsCategoryAdapter.class
public class ClubsCategoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ImageFetcher mImageFetcher;
public ClubsCategoryAdapter(Context context, ArrayList<ClubsCategoryParser.ClubsCategory> clubsCategoryList, ImageFetcher mImageFetcher) {
this.context = context;
this.clubsCategoryList = clubsCategoryList;
this.mImageFetcher = mImageFetcher;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final ViewHolder viewHolder = (ViewHolder) holder;
final ClubsCategoryParser.ClubsCategory singleItem = clubsCategoryList.get(position);
if (!TextUtils.isNullOrEmpty(singleItem.image_url)) {
mImageFetcher.loadImage(singleItem.image_url, String.valueOf(singleItem.ID), viewHolder.imgCategoryIcon);
}
метод LoadImage в ImageWorker.class (DisplayingBitmaps)
public void loadImage(Object data, String imageID, ImageView imageView) {
if (data == null) {
return;
}
BitmapDrawable value = null;
if (mImageCache != null) {
value = mImageCache.getBitmapFromMemCache(imageID);
}
if (value != null) {
// Bitmap found in memory cache
imageView.setImageDrawable(value);
} else if (cancelPotentialWork(data, imageView)) {
//BEGIN_INCLUDE(execute_background_task)
final BitmapWorkerTask task = new BitmapWorkerTask(data, imageID, imageView);
final AsyncDrawable asyncDrawable = new AsyncDrawable(mResources, mLoadingBitmap, task);
imageView.setImageDrawable(asyncDrawable);
// NOTE: This uses a custom version of AsyncTask that has been pulled from the
// framework and slightly modified. Refer to the docs at the top of the class
// for more info on what was changed.
task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
//END_INCLUDE(execute_background_task)
}
}
фактическое AsyncTask для обработки изображения асинхронно
/**
* The actual AsyncTask that will asynchronously process the image.
*/
private class BitmapWorkerTask extends AsyncTask<Void, Void, BitmapDrawable> {
private Object mData;
private String imageID;
private final WeakReference<ImageView> imageViewReference;
public BitmapWorkerTask(Object data, String imageID, ImageView imageView) {
mData = data;
this.imageID = imageID;
imageViewReference = new WeakReference<ImageView>(imageView);
}
/**
* Background processing.
*/
@Override
protected BitmapDrawable doInBackground(Void... params) {
//BEGIN_INCLUDE(load_bitmap_in_background)
if (BuildConfig.DEBUG) {
PrintLog.error(TAG, "doInBackground - starting work");
}
final String dataString = String.valueOf(mData);
Bitmap bitmap = null;
BitmapDrawable drawable = null;
// Wait here if work is paused and the task is not cancelled
synchronized (mPauseWorkLock) {
while (mPauseWork && !isCancelled()) {
try {
Log.e("pauseWork", "iswaiting -------------");
mPauseWorkLock.wait();
} catch (InterruptedException e) {
}
}
}
Log.e("pauseWork", "iswaiting end -------------");
// If the image cache is available and this task has not been cancelled by another
// thread and the ImageView that was originally bound to this task is still bound back
// to this task and our "exit early" flag is not set then try and fetch the bitmap from
// the cache
if (mImageCache != null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = mImageCache.getBitmapFromDiskCache(imageID);
}
// If the bitmap was not found in the cache and this task has not been cancelled by
// another thread and the ImageView that was originally bound to this task is still
// bound back to this task and our "exit early" flag is not set, then call the main
// process method (as implemented by a subclass)
if (bitmap == null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = processBitmap(mData, imageID);
}
// If the bitmap was processed and the image cache is available, then add the processed
// bitmap to the cache for future use. Note we don't check if the task was cancelled
// here, if it was, and the thread is still running, we may as well add the processed
// bitmap to our cache as it might be used again in the future
if (bitmap != null) {
if (DeviceUtils.hasHoneycomb()) {
// Running on Honeycomb or newer, so wrap in a standard BitmapDrawable
drawable = new BitmapDrawable(mResources, bitmap);
} else {
// Running on Gingerbread or older, so wrap in a RecyclingBitmapDrawable
// which will recycle automagically
drawable = new RecyclingBitmapDrawable(mResources, bitmap);
}
if (mImageCache != null) {
mImageCache.addBitmapToCache(imageID, drawable);
}
}
if (BuildConfig.DEBUG) {
PrintLog.error(TAG, "doInBackground - finished work");
}
return drawable;
//END_INCLUDE(load_bitmap_in_background)
}
/**
* Once the image is processed, associates it to the imageView
*/
@Override
protected void onPostExecute(BitmapDrawable value) {
//BEGIN_INCLUDE(complete_background_work)
// if cancel was called on this task or the "exit early" flag is set then we're done
if (isCancelled() || mExitTasksEarly) {
value = null;
}
final ImageView imageView = getAttachedImageView();
if (value != null && imageView != null) {
if (BuildConfig.DEBUG) {
PrintLog.error(TAG, "onPostExecute - setting bitmap");
}
setImageDrawable(imageView, value);
}
//END_INCLUDE(complete_background_work)
}
@Override
protected void onCancelled(BitmapDrawable value) {
super.onCancelled(value);
synchronized (mPauseWorkLock) {
mPauseWorkLock.notifyAll();
}
}
/**
* Returns the ImageView associated with this task as long as the ImageView's task still
* points to this task as well. Returns null otherwise.
*/
private ImageView getAttachedImageView() {
final ImageView imageView = imageViewReference.get();
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (this == bitmapWorkerTask) {
return imageView;
}
return null;
}
}
Изображения показывают штраф в первый раз при установке приложения, но после убийства приложения и загружает ту же страница показывает изображение с черно/белым фоном.
Я пробовал много примеров и статей .. Но ничего не помогло. Я не знаю, почему это происходит с черно-белым фоном после убийства/выхода из приложения.