Android从库中选择显示内存错误的图像

时间:2013-10-09 06:40:43

标签: android image-gallery

我正在编写一个代码示例,我必须从代​​码库中选择一个代码正在运行的图像但是在从图库中选择图像后,我的 OnActivityResult 中出现 OutOfMemoryError

我能够获得小图像,但是大图像会产生问题。

这是我的代码:

try{
                    Uri selectedImageUri = data.getData();
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    String filePath = cursor.getString(columnIndex);
                    cursor.close();
                    bitmap = BitmapFactory.decodeFile(filePath);
                    _profileImage.setImageBitmap(bitmap);
                    _profileImage.setScaleType(ScaleType.FIT_XY);
                    Constant._addPhotoBitmap=bitmap;
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    Bitmap resizedbitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
                    resizedbitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                    byte [] _byteArray = baos.toByteArray();
                    String base64 = Base64.encodeToString(_byteArray,Base64.DEFAULT);
                    Constant._addPhotoBase64 = base64;
                }catch (OutOfMemoryError e) {
                    e.printStackTrace();
                    Constant.showAlertDialog(Constant.errorTitle,
                            "Image size is too large.Please upload small image.",
                            DriverProfileScreen.this, false);
                }   catch (Exception e) {
                    e.printStackTrace();
                }

6 个答案:

答案 0 :(得分:12)

你是根据它的uri路径直接解码文件..为什么它会抛出异常..在加载图像之前设置一些选项..这将减少图像加载的内存..使用此方法加载图像无论如何你想要的尺寸..

/**
 * returns the thumbnail image bitmap from the given url
 * 
 * @param path
 * @param thumbnailSize
 * @return
 */
private Bitmap getThumbnailBitmap(final String path, final int thumbnailSize) {
    Bitmap bitmap;
    BitmapFactory.Options bounds = new BitmapFactory.Options();
    bounds.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, bounds);
    if ((bounds.outWidth == -1) || (bounds.outHeight == -1)) {
        bitmap = null;
    }
    int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
            : bounds.outWidth;
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inSampleSize = originalSize / thumbnailSize;
    bitmap = BitmapFactory.decodeFile(path, opts);
    return bitmap;
}

答案 1 :(得分:2)

在Android Developer文档中,有一个名为

的主题

有效显示位图

所以请仔细阅读。

<强> http://developer.android.com/training/displaying-bitmaps/index.html

希望这会对你有所帮助。

答案 2 :(得分:0)

一般来说android设备的堆大小只有16MB(因​​设备/操作系统而不同,看后堆大小),如果你加载的是图像并且它的大小超过16MB,它会抛出内存不足,而不是使用Bitmap对于,从SD卡或资源甚至从网络加载图像尝试使用getImageUri,加载位图需要更多内存,或者如果您使用该位图完成工作,则可以将位图设置为null。

因此,您需要使用以下代码缩小图像尺寸:

public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
 try {
     //Decode image size
     BitmapFactory.Options o = new BitmapFactory.Options();
     o.inJustDecodeBounds = true;
     BitmapFactory.decodeStream(new FileInputStream(f),null,o);
     //The new size we want to scale to
     final int REQUIRED_WIDTH=WIDTH;
     final int REQUIRED_HIGHT=HIGHT;
     //Find the correct scale value. It should be the power of 2.
     int scale=1;
     while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
         scale*=2;
     //Decode with inSampleSize
     BitmapFactory.Options o2 = new BitmapFactory.Options();
     o2.inSampleSize=scale;
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
 } catch (FileNotFoundException e) {}
 return null;
 }

答案 3 :(得分:0)

首先缩放位图,然后加载它。它将解决问题。

您可以使用以下方法执行此操作。

private Bitmap getScaledBitmap(Uri uri){
        Bitmap thumb = null ;
        try {
            ContentResolver cr = getContentResolver();
            InputStream in = cr.openInputStream(uri);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize=8;
            thumb = BitmapFactory.decodeStream(in,null,options);
        } catch (FileNotFoundException e) {
            Toast.makeText(PhotoTake.this , "File not found" , Toast.LENGTH_SHORT).show();
        }
        return thumb ; 
    }

希望它有所帮助。

答案 4 :(得分:0)

试试这段代码:

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.ActivityManager;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

public class UserImageLoaderWithCache implements ComponentCallbacks {
private KCLruCache cache;

public UserImageLoaderWithCache(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass() * 1024 * 1024;
cache = new KCLruCache(memoryClass);
}

public void display(String url, ImageView imageview, int defaultresource) {
imageview.setImageResource(defaultresource);
Bitmap image = cache.get(url);
if (image != null) {
imageview.setImageBitmap(image);
}
else {
new SetImageTask(imageview).execute(url);
}
}

private class KCLruCache extends LruCache<String, Bitmap> {

public KCLruCache(int maxSize) {
super(maxSize);
}
}

private class SetImageTask extends AsyncTask<String, Void, Integer> {
private ImageView imageview;
private Bitmap bmp;

public SetImageTask(ImageView imageview) {
this.imageview = imageview;
}

@Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
bmp = getBitmapFromURL(url);
if (bmp != null) {
cache.put(url, bmp);
} else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
} catch (OutOfMemoryError o) {
o.printStackTrace();
return 0;
}
return 1;
}

@Override
protected void onPostExecute(Integer result) {
if (result == 1) {
imageview.setImageBitmap(bmp);
}
super.onPostExecute(result);
}

private Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}catch (OutOfMemoryError o) {
o.printStackTrace();
return null;
}
}
}

public void onLowMemory() {
}

/*public void onTrimMemory(int level) {
if (level >= TRIM_MEMORY_MODERATE) {
cache.evictAll();
}
else if (level >= TRIM_MEMORY_BACKGROUND) {
cache.trimToSize(cache.size() / 2);
}
}*/

public void onConfigurationChanged(Configuration arg0) {
// TODO Auto-generated method stub

}
}

答案 5 :(得分:0)

我使用下面的代码并使用位图将调整大小的Image存储在本地存储中,它就像魅力一样

final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;

        Bitmap b = BitmapFactory.decodeFile(path, options);

此处路径是Uri

中的图片String路径