我正在编写一个代码示例,我必须从代码库中选择一个代码正在运行的图像但是在从图库中选择图像后,我的 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();
}
答案 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
路径