내 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 *를 사용하면 예외가 발생할 수 있습니다. 이미지 데이터 소스의 비트 맵 인수를 어떻게 전달해야합니까? 그 기사에서
을 BitmapFactory.decode 사용 * 예외가 발생할 수 있습니다 "무엇을 의미합니까 ?? 너 그거 해봤 니? –
이미지 파일을 직접 디코딩하여 비트 맵에 할당하고 크기와 크기를 고려하지 않으면 크기가 너무 커져 메모리 제한을 초과 할 수 있습니다. 나는 그것을 시도했다. 그래서 위의 코드를 사용했습니다. –
그게 doInBackground() 메소드가 할 일이고, BitmapWorkerTask 객체도 통과 시켰습니다. –