2014-01-15 4 views
2

내 SD 카드에서 일부 이미지를로드하고 응용 프로그램 레이아웃의 배경으로 설정하려고합니다. OutOfMemory Exception을 얻지 않고 백그라운드에서 수행하도록 효율적으로 처리하려고합니다. 그래서 안드로이드 개발자의 Processing Bitmaps 에서 비트 맵 작업에 관한 정확한 코드를 읽고 사용했습니다. loadBitmap에서 그러나Bitmap 인수를 전달하는 방법은 무엇입니까?

public class ImageLoader { 

    private final Context context; 
    private int imageWidth; 
    private int imageHeight; 

    public ImageLoader(Context context, int imageWidth, int imageHeight) { 

     this.context = context; 
     setImageSize(imageWidth, imageHeight); 
    } 

    public ImageLoader(Context context, int imageSize) { 

     this.context = context; 
     setImageSize(imageSize); 
    } 

    public void setImageSize(int width, int height) { 
     imageWidth = width; 
     imageHeight = height; 
    } 

    public void setImageSize(int size) { 
     setImageSize(size, size); 
    } 

    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 decodeSampleBitmapFromResource(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 boolean cancelPotentialWork(int data, ImageView imageView) { 

     final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); 

     if (bitmapWorkerTask != null) { 

      final int bitmapData = bitmapWorkerTask.data; 

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

    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 void loadBitmap(int resId, ImageView imageView) { 

     if (cancelPotentialWork(resId, imageView)) { 

      final BitmapWorkerTask task = new BitmapWorkerTask(imageView); 

      final AsyncDrawable asyncDrawable = 
        new AsyncDrawable(context.getResources(), ???mPlaceHoderBitmap???, task); 

      imageView.setImageDrawable(asyncDrawable); 

      task.execute(resId); 
     } 
    } 

    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { 

     private final WeakReference<ImageView> imageViewReference; 
     private int data = 0; 

     public BitmapWorkerTask(ImageView imageView) { 

      // Use a WeakReference to ensure the ImageView can be garbage collected 
      imageViewReference = new WeakReference<ImageView>(imageView); 
     } 

     // Decode image in background 
     @Override 
     protected Bitmap doInBackground(Integer... params) { 

      data = params[0]; 
      return decodeSampleBitmapFromResource(context.getResources(), data, imageWidth, imageHeight); 
     } 

     @Override 
     protected void onPostExecute(Bitmap bitmap) { 

      if (isCancelled()) { 
       bitmap = null; 
      } 

      if (imageViewReference != null && bitmap != null) { 

       final ImageView imageView = imageViewReference.get(); 

       final BitmapWorkerTask bitmapWorkerTask = 
         getBitmapWorkerTask(imageView); 

       if (this == bitmapWorkerTask && imageView != null) { 

        imageView.setImageBitmap(bitmap); 
       } 
      } 
     } 

    } 

    static class AsyncDrawable extends BitmapDrawable { 

     private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; 

     public AsyncDrawable(Resources res, Bitmap bitmap, 
       BitmapWorkerTask bitmapWorkerTask) { 

      super(res, bitmap); 

      bitmapWorkerTaskReference = 
        new WeakReference<ImageLoader.BitmapWorkerTask>(bitmapWorkerTask); 
     } 

     public BitmapWorkerTask getBitmapWorkerTask() { 

      return bitmapWorkerTaskReference.get(); 
     } 
    } 
} 

(INT 잔유, 비트 맵 비트 맵 이미지 뷰의 이미지 뷰) 나는 비트 맵을 전달하는 방법을 모르는 방법 : 여기 내 코드입니다. BitmapFactory.decode *를 사용하면 예외가 발생할 수 있습니다. 이미지 데이터 소스의 비트 맵 인수를 어떻게 전달해야합니까? 그 기사에서

+0

을 BitmapFactory.decode 사용 * 예외가 발생할 수 있습니다 "무엇을 의미합니까 ?? 너 그거 해봤 니? –

+0

이미지 파일을 직접 디코딩하여 비트 맵에 할당하고 크기와 크기를 고려하지 않으면 크기가 너무 커져 메모리 제한을 초과 할 수 있습니다. 나는 그것을 시도했다. 그래서 위의 코드를 사용했습니다. –

+0

그게 doInBackground() 메소드가 할 일이고, BitmapWorkerTask 객체도 통과 시켰습니다. –

답변

1

:

당신이 AsyncDrawable에 전달되는 비트 맵은 실제 이미지가로드되는 동안 자리 표시 자 있어야하는데
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); 
    } 
} 

.

이렇게하면 장소 소유자 이미지를 한 번 디코딩하고 전달할 수 있습니다.

활동에 비트 맵 객체를 만듭니다

Bitmap placeHolder=null; 

지금 onCreate

placeHolder=BitmapFactory.decodeResource(getResources(), R.drawable.place_holder); 

당신이 SD 카드의 통화에서 일부 이미지를로드 할 때마다 다음과 같은 경우 "

loadBitmap(<resId>,placeHolder,imageView); 
+0

에 null을 전달하려고하면 DecodeFile과 같은 BitmapFactory.decode * 메소드 중 하나를 사용하고 이미지를 전달한다는 것을 의미합니까? –

+0

이미지 위치 홀더가 의미하는 바를 이해하지 못합니다. –

+0

네 번만 한 번. res/drawable에 place holder 이미지를 넣고 onCreate에서 디코드 한 다음 그 객체를 그냥 넘겨 준다. –

관련 문제