Showing posts with label Bitmap. Show all posts
Showing posts with label Bitmap. Show all posts

Wednesday, March 28, 2012

OutOfMemoryError when using bitmap in Android?


The most common issue that you may face while working with bitmap is OutOfMemoryError. This issue occur because the garbage collector (GC) does not free the object associated with the bitmap and clear preference to pixel data fast enough, thus cause the memory allocated for the bitmap to grow until exceeding Virtual Memory limit.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
In order to avoid this issue, you need to do recycle() for every bitmap as soon as it no long need. Notice that recycle () is used to free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as “dead”, meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing. This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap. See the code below:
public class bitmaptest extends Activity {

     @Override
     public void onCreate(Bundle icicle) {
          super.onCreate(icicle);
          // decode a jpg into bitmap
          Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/myimage.jpg");

          ...

          // indicate that the bitmap is no longer need and GC should
          // free it asap
          bitmap.recycle();
     }
}
 
Bimap is a little tricky, miss-use it may causes an exception. Generally using bitmap is recommended only if you need to get detail data of the image such as image width, height, and pixel data. Otherwise, bitmap should not be used in order to avoid OutOfMemoryError. For an example, if you just want to dispaly an image such as icon, you could you ImageView class instead and it also provides various display options such as scaling and tinting. The following code below shows how to build an ImageView that uses an image from drawable resources and add it to the layout.
public class bitmaptest extends Activity {

     private LinearLayout mLinearLayout;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);

          // Create a LinearLayout in which to add the ImageView
          mLinearLayout = new LinearLayout(this);

          // Instantiate an ImageView and define its properties
          ImageView imageView = new ImageView(this);
          imageView.setImageResource(R.drawable.my_image);
          imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
          imageView.setPadding(8, 8, 8, 8);
          imageView.setLayoutParams(new GridView.LayoutParams(200, 200));

          // Add the ImageView to the layout and set the layout as
          // the content view
          mLinearLayout.addView(imageView);
          setContentView(mLinearLayout);
     }
}


Friday, March 23, 2012

Combining 2 Images in Android using Canvas ?


Below are the methods to canvert the two bitmap in to one..........


 private BitmapDrawable createUserMarker(Bitmap bmp1, Bitmap bmp2) {
Bitmap bitmapStar = bmp1;
Bitmap bmOverlay = Bitmap.createBitmap(bmp2.getWidth(), bmp2.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawARGB(0x00, 0, 0, 0);
canvas.drawBitmap(bmp2, 0, 0, null);
canvas.drawBitmap(bitmapStar, 2, 2, null);
BitmapDrawable dr = new BitmapDrawable(bmOverlay);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
return (dr);
    }


OR


 public Bitmap combineImages(Bitmap c, Bitmap s) { 
// can add a 3rd parameter 'String loc' if you want to save the new
// image - left some code to do that at the bottom 
   Bitmap cs = null; 
 
   int width, height = 0; 
    
   if(c.getWidth() > s.getWidth()) { 
     width = c.getWidth(); 
     height = c.getHeight() + s.getHeight(); 
   } else { 
     width = s.getWidth(); 
     height = c.getHeight() + s.getHeight(); 
   } 
 
   cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
 
   Canvas comboImage = new Canvas(cs); 
 
   comboImage.drawBitmap(c, 0f, 0f, null); 
   comboImage.drawBitmap(s, 0f, c.getHeight(), null); 
 
   // this is an extra bit I added, just incase you want to save the new image somewhere and then return the location 
   /*String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png"; 
 
   OutputStream os = null; 
   try { 
     os = new FileOutputStream(loc + tmpImg); 
     cs.compress(CompressFormat.PNG, 100, os); 
   } catch(IOException e) { 
     Log.e("combineImages", "problem combining images", e); 
   }*/ 
 
   return cs; 
 }