2016-03-24 35 views
1

Im mit DisplayingBitmap.zip von der Android-Website heruntergeladen, um Bilder asynchron in die Bildansicht zu laden. Ich empfange Base64 Strings vom Webservice. so änderte der Code, um base64 zu Bitmap in ImageFetcher.class zu konvertieren (DisplayingBitmaps), anstatt Bild von URL herunterzuladen.ImageView zeigt schwarz/weiß Hintergrund für transparente Base64 Zeichenfolge Bild

HINWEIS: Im Empfangen von GIF-Bildern in Form von Base64-Zeichenfolge.

Base64 Converting

 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; 
     } 
    } 

Converting Base64 Bitmap Bitmap Inorder Datei zu erhalten dekodierten Größe geänderte Bitmap mit processBitmap Methode in ImageFetcher.class (DisplayingBitmaps): decodeSampledBitmapFromFile

/** 
     * 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); 
     } 

Methode von 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); 
    } 

Implementierung ImageFetcher.class (DisplayingBitmaps.zip) in meiner Klasse

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); 
    } 

Bestehen dieser mImageFetcher Objektklasse Adapter Bilder für jedes Element asynchron zu laden.

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 Verfahren in 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) 
     } 
    } 

tatsächliche AsyncTask das Bild zu verarbeiten asynchron

/** 
    * 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; 
     } 
    } 

Bilder zeigen feine zum ersten Mal, wenn die App zu installieren, aber nach der App zu töten und lädt die gleiche Seite zeigt das Bild mit dem schwarzen/weißen Hintergrund.

Ich habe viele Beispiele und Artikel ausprobiert .. Aber nichts half. Ich weiß nicht, warum es mit dem schwarz/weißen Hintergrund nach dem Töten/Beenden der App kommt.

Antwort

1

Ihre App zeigt das Bild zum ersten Mal an und zeigt einen schwarzen Hintergrund nach der Re-Opening-App, da die App "DisplayingBitmap" die Bilder im JPEG-Format im Dateisystem zwischenspeichert. Wie Sie wissen, unterstützt JPEG den transparenten Modus nicht.

Bitte öffnen Imagecache Klasse und Blick auf die # 68 Linie:

private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG; 

schwarzen Hintergrund zu vermeiden ich diesen Wert auf PNG-Format geändert:

private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.PNG; 

UPDATE:

Sie können auch comp RessFormat zu JPEG:

ImageCache.ImageCacheParams cacheParams = new ImageCache.ImageCacheParams(getActivity(), IMAGE_CACHE_DIR); 
     cacheParams.setMemCacheSizePercent(0.25f); 
cacheParams.compressFormat = Bitmap.CompressFormat.JPEG; 

es funktioniert für mich und hoffe, dass es Ihnen hilft.

Verwandte Themen