Reputation: 75
First i call MediaStore.ACTION_IMAGE_CAPTURE intent to open camera then i get the saved captured image path from this function.
private String getLastImageId(){
String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
if(imageCursor.moveToFirst()){
int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
//imageCursor.close();
return fullPath;
}else{
return "";
}
}
then i pass that path to a product object attribute as a parameter. add that object to product list that list is displayed by a customized adapter. i am displaying the product title and image in the listView
in customized adapter class i get the product fetch product title and path from it make a bitmap from path and asign it to the product holder that contain a image view working this way for first photo is fine but on the second photo it gives the exception of java.lang.outofmemory i have also tried the solution given at
java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android
doing so as in product adapter
public class ProductAdopter extends ArrayAdapter<Product> {
Context context;
int layoutResourceId;
ArrayList<Product> data = null;
public ProductAdopter(Context context, int layoutResourceId, ArrayList<Product> product_data) {
// TODO Auto-generated constructor stub
super(context, layoutResourceId, product_data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = product_data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ProductHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((MainActivity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ProductHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (ProductHolder)row.getTag();
}
Product product = data.get(position);
holder.txtTitle.setText(product.getName());
File imgFile = new File(product.icon);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
holder.imgIcon.setImageBitmap(myBitmap);
//myBitmap.recycle();
}
return row;
}
static class ProductHolder
{
ImageView imgIcon;
TextView txtTitle;
}
}
Upvotes: 1
Views: 3485
Reputation: 3095
OutOfMemory can be tiring here are some few options that you can look
try {
//Create your bitmap here
} catch (OutOfMemoryError ooM) {
// You got out of memory now do something to recycle images
// Yes you can catch OOM.
recycle();
}
If you do not have many images to handle then you can try this.
BitmapFactory.Options op = new BitmapFactory.Options();
op.inSampleSize = 8;
return BitmapFactory.decodeFile("<YOUR IMAGE FILE HERE>", op);
A combination of above can be useful if you have many images
Upvotes: 0
Reputation: 9035
if(imgFile.exists()){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(),options);
holder.imgIcon.setImageBitmap(myBitmap);
//myBitmap.recycle();
}
Use inSampleSize to load scales bitmaps to memory. Using powers of 2 for inSampleSize values is faster and more efficient for the decoder. However, if you plan to cache the resized versions in memory or on disk, it’s usually still worth decoding to the most appropriate image dimensions to save space.
For more see Loading Large Bitmaps Efficiently
Upvotes: 5
Reputation: 15798
You will run into out of memory issues if you try to decode big images yourself.
Try using Universal Image loader. It will take care of all image loading from local storage or the internet.
https://github.com/nostra13/Android-Universal-Image-Loader
Upvotes: 0