Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将图像加载到位图对象时出现奇怪的OutOfMemory问题_Android_Image_Bitmap_Out Of Memory_Android Bitmap - Fatal编程技术网

Android 将图像加载到位图对象时出现奇怪的OutOfMemory问题

Android 将图像加载到位图对象时出现奇怪的OutOfMemory问题,android,image,bitmap,out-of-memory,android-bitmap,Android,Image,Bitmap,Out Of Memory,Android Bitmap,我有一个列表视图,每行有两个图像按钮。当用户单击列表行时,它将启动一个新活动。由于相机布局的问题,我不得不创建自己的选项卡。为结果启动的活动是一个映射。如果单击我的按钮启动图像预览(从SD卡加载图像),应用程序将从活动返回到结果处理程序的ListView活动,以重新启动我的新活动,它只不过是一个图像小部件 正在使用光标和ListAdapter在ListView上进行图像预览。这使它变得非常简单,但我不确定如何将调整大小的图像(即较小的位大小而不是像素)作为动态图像按钮的src。因此,我只是调整了

我有一个
列表视图
,每行有两个图像按钮。当用户单击列表行时,它将启动一个新活动。由于相机布局的问题,我不得不创建自己的选项卡。为结果启动的活动是一个映射。如果单击我的按钮启动图像预览(从SD卡加载图像),应用程序将从活动返回到结果处理程序的
ListView
活动,以重新启动我的新活动,它只不过是一个图像小部件

正在使用光标和
ListAdapter
ListView
上进行图像预览。这使它变得非常简单,但我不确定如何将调整大小的图像(即较小的位大小而不是像素)作为动态图像按钮的
src
。因此,我只是调整了手机摄像头的图像大小

问题是,当它试图返回并重新启动第二个活动时,我收到一个
OutOfMemoryError

  • 有没有一种方法可以让我一行一行地轻松构建列表适配器,从而可以动态调整大小(按位)
由于焦点问题,我无法使用触摸屏选择行,因此我还需要对每行中的小部件/元素的属性进行一些更改,因此这将是更好的选择。(我可以使用rollerball。)

  • 我知道我可以做带外调整大小和保存我的图像,但这不是我真正想要做的,但一些示例代码会很好
当我在
列表视图中禁用图像时,它又恢复了正常工作

仅供参考:我就是这样做的:

String[]from=new String[]{DBHelper.KEY\u BUSINESSNAME,DBHelper.KEY\u ADDRESS,
DBHelper.KEY_CITY,DBHelper.KEY_GPSLONG,DBHelper.KEY_GPSLAT,
DBHelper.KEY_IMAGEFILENAME+“”};
int[]to=new int[]{R.id.businessname,R.id.address,R.id.city,R.id.gpslong,
R.id.gpslat,R.id.imagefilename};
notes=新的SimpleCursorAdapter(this,R.layout.notes_行,c,from,to);
setListAdapter(注释);
其中
R.id.imagefilename
是一个
按钮图像

这是我的日志:

01-25 05:05:49.877: ERROR/dalvikvm-heap(3896): 6291456-byte external allocation too large for this process.
01-25 05:05:49.877: ERROR/(3896): VM wont let us allocate 6291456 bytes
01-25 05:05:49.877: ERROR/AndroidRuntime(3896): Uncaught handler: thread main exiting due to uncaught exception
01-25 05:05:49.917: ERROR/AndroidRuntime(3896): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:304)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:149)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:174)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.drawable.Drawable.createFromPath(Drawable.java:729)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ImageView.resolveUri(ImageView.java:484)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ImageView.setImageURI(ImageView.java:281)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.SimpleCursorAdapter.setViewImage(SimpleCursorAdapter.java:183)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:129)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.CursorAdapter.getView(CursorAdapter.java:150)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.AbsListView.obtainView(AbsListView.java:1057)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.makeAndAddView(ListView.java:1616)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.fillSpecific(ListView.java:1177)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.layoutChildren(ListView.java:1454)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.AbsListView.onLayout(AbsListView.java:937)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1108)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.onLayout(LinearLayout.java:922)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.FrameLayout.onLayout(FrameLayout.java:294)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:999)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.onLayout(LinearLayout.java:920)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.FrameLayout.onLayout(FrameLayout.java:294)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.ViewRoot.performTraversals(ViewRoot.java:771)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1103)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.os.Handler.dispatchMessage(Handler.java:88)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.os.Looper.loop(Looper.java:123)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.app.ActivityThread.main(ActivityThread.java:3742)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at java.lang.reflect.Method.invokeNative(Native Method)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at java.lang.reflect.Method.invoke(Method.java:515)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at dalvik.system.NativeStart.main(Native Method)
01-25 05:10:01.127: ERROR/AndroidRuntime(3943): ERROR: thread attach failed 
在显示图像时,我还有一个新错误:

22:13:18.594: DEBUG/skia(4204): xxxxxxxxxxx jpeg error 20 Improper call to JPEG library in state %d
22:13:18.604: INFO/System.out(4204): resolveUri failed on bad bitmap uri: 
22:13:18.694: ERROR/dalvikvm-heap(4204): 6291456-byte external allocation too large for this process.
22:13:18.694: ERROR/(4204): VM won't let us allocate 6291456 bytes
22:13:18.694: DEBUG/skia(4204): xxxxxxxxxxxxxxxxxxxx allocPixelRef failed

我做了以下步骤来拍摄图像并动态调整其大小。希望这能有所帮助

Bitmap bm;
bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(filepath), 100, 100, true);
mPicture = new ImageView(context);
mPicture.setImageBitmap(bm);    

要修复OutOfMemory错误,应执行以下操作:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null, options);
inSampleSize
选项可减少内存消耗

这里有一个完整的方法。首先它读取图像大小而不解码内容本身。然后它找到最佳的
inSampleSize
值,它应该是2的幂,最后图像被解码

// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
    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_SIZE=70;

        // Find the correct scale value. It should be the power of 2.
        int scale = 1;
        while(o.outWidth / scale / 2 >= REQUIRED_SIZE && 
              o.outHeight / scale / 2 >= REQUIRED_SIZE) {
            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;
}

我对Fedor的代码做了一点小小的改进。它基本上也是这样,但没有(在我看来)丑陋的while循环,它总是得到二次幂。Fedor做出了最初的解决方案,这让我感到很荣幸,直到我找到了他的解决方案,然后我才做出了这个:)


使用这个
bitmap.recycle()这有助于避免任何图像质量问题。

我有一个更有效的解决方案,它不需要任何类型的缩放。只需对位图解码一次,然后根据位图名称将其缓存在地图中。然后根据名称检索位图并在ImageView中进行设置。没有什么需要做的了

这将起作用,因为解码位图的实际二进制数据不存储在dalvik VM堆中。它存储在外部。因此,每次解码位图时,它都会在VM堆之外分配内存,而VM堆永远不会被GC回收

为了帮助您更好地理解这一点,假设您将您的图像保存在可绘制文件夹中。您只需执行一个getResources().getDrwable(R.drawable.)即可获得图像。这不会每次都对图像进行解码,但每次调用时都会重复使用已解码的实例。所以本质上它是缓存的

现在,由于您的图像位于某个文件中(甚至可能来自外部服务器),因此您有责任缓存解码后的位图实例,以便在需要的任何位置重复使用


希望这能有所帮助。

这里有两个问题

  • 位图内存不在VM堆中,而是在本机堆中-请参阅
  • 本机堆的垃圾收集比VM堆慢,因此每次执行活动的onPause或onDestroy时,都需要非常积极地执行bitmap.recycle和bitmap=null

    • 这似乎是一个长期存在的问题,有很多不同的解释。我采纳了这里提供的两个最常见答案的建议,但这两个答案都没有解决我的问题,即VM声称它负担不起执行解码过程的部分的字节数。经过一番挖掘,我了解到这里真正的问题是从本机堆中取出的解码过程

      请看这里:

      这就引出了另一个讨论主题,在这里我找到了解决这个问题的更多方法。一种是调用
      System.gc()显示图像后手动执行。但这实际上会让你的应用程序使用更多内存,从而减少本机堆。自2.0(Donut)发布以来,更好的解决方案是使用BitmapFactory选项“Inpurgable”。所以我简单地添加了
      o2.inpurgable=true紧跟在
      o2之后。inSampleSize=刻度

      有关该主题的更多信息,请参见:

      说到这里,我对Java和Android也是个十足的傻瓜。所以,如果你认为这是解决这个问题的一个糟糕的方法,你可能是对的但这给我带来了奇迹,我发现现在无法从堆缓存中运行VM。我能找到的唯一缺点是,您正在破坏缓存绘制的图像。这意味着如果你直接回到那个图像,你每次都在重画它。就我的应用程序的工作方式而言
       private Bitmap decodeFile(File f){
          Bitmap b = null;
      
              //Decode image size
          BitmapFactory.Options o = new BitmapFactory.Options();
          o.inJustDecodeBounds = true;
      
          FileInputStream fis = new FileInputStream(f);
          BitmapFactory.decodeStream(fis, null, o);
          fis.close();
      
          int scale = 1;
          if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
              scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE / 
                 (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
          }
      
          //Decode with inSampleSize
          BitmapFactory.Options o2 = new BitmapFactory.Options();
          o2.inSampleSize = scale;
          fis = new FileInputStream(f);
          b = BitmapFactory.decodeStream(fis, null, o2);
          fis.close();
      
          return b;
      }
      
      public static Drawable getAssetImage(Context context, String filename) throws IOException {
          AssetManager assets = context.getResources().getAssets();
          InputStream buffer = new BufferedInputStream((assets.open("drawable/" + filename + ".png")));
          Bitmap bitmap = BitmapFactory.decodeStream(buffer);
          return new BitmapDrawable(context.getResources(), bitmap);
      }
      
      Bitmap b = null;
      Drawable d;
      ImageView i = new ImageView(mContext);
      try {
          b = Bitmap.createBitmap(320,424,Bitmap.Config.RGB_565);
          b.eraseColor(0xFFFFFFFF);
          Rect r = new Rect(0, 0,320 , 424);
          Canvas c = new Canvas(b);
          Paint p = new Paint();
          p.setColor(0xFFC0C0C0);
          c.drawRect(r, p);
          d = mContext.getResources().getDrawable(mImageIds[position]);
          d.setBounds(r);
          d.draw(c);
      
          /*   
              BitmapFactory.Options o2 = new BitmapFactory.Options();
              o2.inTempStorage = new byte[128*1024];
              b = BitmapFactory.decodeStream(mContext.getResources().openRawResource(mImageIds[position]), null, o2);
              o2.inSampleSize=16;
              o2.inPurgeable = true;
          */
      } catch (Exception e) {
      
      }
      i.setImageBitmap(b);
      
      private void showImage(String path)   {
      
          Log.i("showImage","loading:"+path);
          BitmapFactory.Options bfOptions=new BitmapFactory.Options();
          bfOptions.inDither=false;                     //Disable Dithering mode
          bfOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
          bfOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
          bfOptions.inTempStorage=new byte[32 * 1024]; 
      
          File file=new File(path);
          FileInputStream fs=null;
          try {
              fs = new FileInputStream(file);
          } catch (FileNotFoundException e) {
              //TODO do something intelligent
              e.printStackTrace();
          }
      
          try {
              if(fs!=null) bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
          } catch (IOException e) {
              //TODO do something intelligent
              e.printStackTrace();
          } finally{ 
              if(fs!=null) {
                  try {
                      fs.close();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
          }
          //bm=BitmapFactory.decodeFile(path, bfOptions); This one causes error: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
      
          im.setImageBitmap(bm);
          //bm.recycle();
          bm=null;                        
      }
      
      if (bitmap != null)
      {
        bitmap.recycle();
        bitmap = null;
      }
      if (imageView != null)
      {
        imageView.setImageResource(R.drawable.tiny); // This is my 1x1 png.
      }
      System.gc();
      
      imageView.setImageBitmap(...); // Do whatever you need to do to load the image you want.
      
      @Override
      public View getView(final int position, View convertView, final ViewGroup parent) {
      
          if(convertView == null){
              LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = inflater.inflate(R.layout.spinner_row, null);
          }
      ...
      
      @Override
      public void onDestroy()
      {   
          Cleanup();
          super.onDestroy();
      }
      
      private void Cleanup()
      {    
          bitmap.recycle();
          System.gc();
          Runtime.getRuntime().gc();  
      }
      
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
      int imageHeight = options.outHeight;
      int imageWidth = options.outWidth;
      String imageType = options.outMimeType;
      
      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 decodeSampledBitmapFromResource(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);
      }
      
      mImageView.setImageBitmap(
          decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
      
      public Bitmap readAssetsBitmap(String filename) throws IOException {
          try {
              BitmapFactory.Options options = new BitmapFactory.Options(); 
              options.inPurgeable = true;
              Bitmap bitmap = BitmapFactory.decodeStream(assets.open(filename), null, options);
              if(bitmap == null) {
                  throw new IOException("File cannot be opened: It's value is null");
              } else {
                  return bitmap;
              }
          } catch (IOException e) {
              throw new IOException("File cannot be opened: " + e.getMessage());
          }
      }
      
      public Cache(int size, int maxWidth, int maxHeight) {
          // Into the constructor you add the maximum pixels
          // that you want to allow in order to not scale images.
          mMaxWidth = maxWidth;
          mMaxHeight = maxHeight;
      
          mBitmapCache = new LruCache<String, Bitmap>(size) {
              protected int sizeOf(String key, Bitmap b) {
                  // Assuming that one pixel contains four bytes.
                  return b.getHeight() * b.getWidth() * 4;
              }
          };
      
          mCurrentTasks = new ArrayList<String>();    
      }
      
      /**
       * Gets a bitmap from cache. 
       * If it is not in cache, this method will:
       * 
       * 1: check if the bitmap url is currently being processed in the
       * BitmapLoaderTask and cancel if it is already in a task (a control to see
       * if it's inside the currentTasks list).
       * 
       * 2: check if an internet connection is available and continue if so.
       * 
       * 3: download the bitmap, scale the bitmap if necessary and put it into
       * the memory cache.
       * 
       * 4: Remove the bitmap url from the currentTasks list.
       * 
       * 5: Notify the ListAdapter.
       * 
       * @param mainActivity - Reference to activity object, in order to
       * call notifyDataSetChanged() on the ListAdapter.
       * @param imageKey - The bitmap url (will be the key).
       * @param imageView - The ImageView that should get an
       * available bitmap or a placeholder image.
       * @param isScrolling - If set to true, we skip executing more tasks since
       * the user probably has flinged away the view.
       */
      public void loadBitmap(MainActivity mainActivity, 
              String imageKey, ImageView imageView,
              boolean isScrolling) {
          final Bitmap bitmap = getBitmapFromCache(imageKey); 
      
          if (bitmap != null) {
              imageView.setImageBitmap(bitmap);
          } else {
              imageView.setImageResource(R.drawable.ic_launcher);
              if (!isScrolling && !mCurrentTasks.contains(imageKey) && 
                      mainActivity.internetIsAvailable()) {
                  BitmapLoaderTask task = new BitmapLoaderTask(imageKey,
                          mainActivity.getAdapter());
                  task.execute();
              }
          } 
      }
      
      public void onScrollStateChanged(AbsListView view, int scrollState) {
          if (view.getId() == android.R.id.list) {
              // Set scrolling to true only if the user has flinged the       
              // ListView away, hence we skip downloading a series
              // of unnecessary bitmaps that the user probably
              // just want to skip anyways. If we scroll slowly it
              // will still download bitmaps - that means
              // that the application won't wait for the user
              // to lift its finger off the screen in order to
              // download.
              if (scrollState == SCROLL_STATE_FLING) {
                  mIsScrolling = true;
              } else {
                  mIsScrolling = false;
                  mListAdapter.notifyDataSetChanged();
              }
          } 
      }
      
      // Inside ListAdapter...
      @Override
      public View getView(final int position, View convertView, ViewGroup parent) {           
          View row = convertView;
          final ViewHolder holder;
      
          if (row == null) {
              LayoutInflater inflater = getLayoutInflater();
              row = inflater.inflate(R.layout.main_listview_row, parent, false);  
              holder = new ViewHolder(row);
              row.setTag(holder);
          } else {
              holder = (ViewHolder) row.getTag();
          }   
      
          final Row rowObject = getItem(position);
      
          // Look at the loadBitmap() method description...
          holder.mTextView.setText(rowObject.mText);      
          mCache.loadBitmap(MainActivity.this,
                  rowObject.mBitmapUrl, holder.mImageView,
                  mIsScrolling);  
      
          return row;
      }
      
      Bitmap myBitmap;
      
      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.InPurgeable = true;
      options.OutHeight = 50;
      options.OutWidth = 50;
      options.InSampleSize = 4;
      
      File imgFile = new File(filepath);
      myBitmap = BitmapFactory.DecodeFile(imgFile.AbsolutePath, options);
      
      public class BitmapUtilsTask extends AsyncTask<Object, Void, Bitmap> {
      
          Context context;
      
          public BitmapUtilsTask(Context context) {
              this.context = context;
          }
      
          /**
           * Loads a bitmap from the specified url.
           * 
           * @param url The location of the bitmap asset
           * @return The bitmap, or null if it could not be loaded
           * @throws IOException
           * @throws MalformedURLException
           */
          public Bitmap getBitmap() throws MalformedURLException, IOException {       
      
              // Get the source image's dimensions
              int desiredWidth = 1000;
              BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds = true;
      
              BitmapFactory.decodeResource(context.getResources(), R.drawable.green_background , options);
      
              int srcWidth = options.outWidth;
              int srcHeight = options.outHeight;
      
              // Only scale if the source is big enough. This code is just trying
              // to fit a image into a certain width.
              if (desiredWidth > srcWidth)
                  desiredWidth = srcWidth;
      
              // Calculate the correct inSampleSize/scale value. This helps reduce
              // memory use. It should be a power of 2
              int inSampleSize = 1;
              while (srcWidth / 2 > desiredWidth) {
                  srcWidth /= 2;
                  srcHeight /= 2;
                  inSampleSize *= 2;
              }
              // Decode with inSampleSize
              options.inJustDecodeBounds = false;
              options.inDither = false;
              options.inSampleSize = inSampleSize;
              options.inScaled = false;
              options.inPreferredConfig = Bitmap.Config.ARGB_8888;
              options.inPurgeable = true;
              Bitmap sampledSrcBitmap;
      
              sampledSrcBitmap =  BitmapFactory.decodeResource(context.getResources(), R.drawable.green_background , options);
      
              return sampledSrcBitmap;
          }
      
          /**
           * The system calls this to perform work in a worker thread and delivers
           * it the parameters given to AsyncTask.execute()
           */
          @Override
          protected Bitmap doInBackground(Object... item) {
              try { 
                return getBitmap();
              } catch (MalformedURLException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return null;
          }
      }
      
      package com.emil;
      
      import java.io.IOException;
      import java.io.InputStream;
      
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      
      /**
       * A class to load and process images of various sizes from input streams and file paths.
       * 
       * @author Emil http://stackoverflow.com/users/220710/emil
       *
       */
      public class ImageProcessing {
      
          public static Bitmap getBitmap(InputStream stream, int sampleSize, Bitmap.Config bitmapConfig) throws IOException{
              BitmapFactory.Options options=ImageProcessing.getOptionsForSampling(sampleSize, bitmapConfig);
              Bitmap bm = BitmapFactory.decodeStream(stream,null,options);
              if(ImageProcessing.checkDecode(options)){
                  return bm;
              }else{
                  throw new IOException("Image decoding failed, using stream.");
              }
          }
      
          public static Bitmap getBitmap(String imgPath, int sampleSize, Bitmap.Config bitmapConfig) throws IOException{
              BitmapFactory.Options options=ImageProcessing.getOptionsForSampling(sampleSize, bitmapConfig);
              Bitmap bm = BitmapFactory.decodeFile(imgPath,options);
              if(ImageProcessing.checkDecode(options)){
                  return bm;
              }else{
                  throw new IOException("Image decoding failed, using file path.");
              }
          }
      
          public static Dimensions getDimensions(InputStream stream) throws IOException{
              BitmapFactory.Options options=ImageProcessing.getOptionsForDimensions();
              BitmapFactory.decodeStream(stream,null,options);
              if(ImageProcessing.checkDecode(options)){
                  return new ImageProcessing.Dimensions(options.outWidth,options.outHeight);
              }else{
                  throw new IOException("Image decoding failed, using stream.");
              }
          }
      
          public static Dimensions getDimensions(String imgPath) throws IOException{
              BitmapFactory.Options options=ImageProcessing.getOptionsForDimensions();
              BitmapFactory.decodeFile(imgPath,options);
              if(ImageProcessing.checkDecode(options)){
                  return new ImageProcessing.Dimensions(options.outWidth,options.outHeight);
              }else{
                  throw new IOException("Image decoding failed, using file path.");
              }
          }
      
          private static boolean checkDecode(BitmapFactory.Options options){
              // Did decode work?
              if( options.outWidth<0 || options.outHeight<0 ){
                  return false;
              }else{
                  return true;
              }
          }
      
          /**
           * Creates a Bitmap that is of the minimum dimensions necessary
           * @param bm
           * @param min
           * @return
           */
          public static Bitmap createMinimalBitmap(Bitmap bm, ImageProcessing.Minimize min){
              int newWidth, newHeight;
              switch(min.type){
              case WIDTH:
                  if(bm.getWidth()>min.minWidth){
                      newWidth=min.minWidth;
                      newHeight=ImageProcessing.getScaledHeight(newWidth, bm);
                  }else{
                      // No resize
                      newWidth=bm.getWidth();
                      newHeight=bm.getHeight();
                  }
                  break;
              case HEIGHT:
                  if(bm.getHeight()>min.minHeight){
                      newHeight=min.minHeight;
                      newWidth=ImageProcessing.getScaledWidth(newHeight, bm);
                  }else{
                      // No resize
                      newWidth=bm.getWidth();
                      newHeight=bm.getHeight();
                  }
                  break;
              case BOTH: // minimize to the maximum dimension
              case MAX:
                  if(bm.getHeight()>bm.getWidth()){
                      // Height needs to minimized
                      min.minDim=min.minDim!=null ? min.minDim : min.minHeight;
                      if(bm.getHeight()>min.minDim){
                          newHeight=min.minDim;
                          newWidth=ImageProcessing.getScaledWidth(newHeight, bm);
                      }else{
                          // No resize
                          newWidth=bm.getWidth();
                          newHeight=bm.getHeight();
                      }
                  }else{
                      // Width needs to be minimized
                      min.minDim=min.minDim!=null ? min.minDim : min.minWidth;
                      if(bm.getWidth()>min.minDim){
                          newWidth=min.minDim;
                          newHeight=ImageProcessing.getScaledHeight(newWidth, bm);
                      }else{
                          // No resize
                          newWidth=bm.getWidth();
                          newHeight=bm.getHeight();
                      }
                  }
                  break;
              default:
                  // No resize
                  newWidth=bm.getWidth();
                  newHeight=bm.getHeight();
              }
              return Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);
          }
      
          public static int getScaledWidth(int height, Bitmap bm){
              return (int)(((double)bm.getWidth()/bm.getHeight())*height);
          }
      
          public static int getScaledHeight(int width, Bitmap bm){
              return (int)(((double)bm.getHeight()/bm.getWidth())*width);
          }
      
          /**
           * Get the proper sample size to meet minimization restraints
           * @param dim
           * @param min
           * @param multipleOf2 for fastest processing it is recommended that the sample size be a multiple of 2
           * @return
           */
          public static int getSampleSize(ImageProcessing.Dimensions dim, ImageProcessing.Minimize min, boolean multipleOf2){
              switch(min.type){
              case WIDTH:
                  return ImageProcessing.getMaxSampleSize(dim.width, min.minWidth, multipleOf2);
              case HEIGHT:
                  return ImageProcessing.getMaxSampleSize(dim.height, min.minHeight, multipleOf2);
              case BOTH:
                  int widthMaxSampleSize=ImageProcessing.getMaxSampleSize(dim.width, min.minWidth, multipleOf2);
                  int heightMaxSampleSize=ImageProcessing.getMaxSampleSize(dim.height, min.minHeight, multipleOf2);
                  // Return the smaller of the two
                  if(widthMaxSampleSize<heightMaxSampleSize){
                      return widthMaxSampleSize;
                  }else{
                      return heightMaxSampleSize;
                  }
              case MAX:
                  // Find the larger dimension and go bases on that
                  if(dim.width>dim.height){
                      return ImageProcessing.getMaxSampleSize(dim.width, min.minDim, multipleOf2);
                  }else{
                      return ImageProcessing.getMaxSampleSize(dim.height, min.minDim, multipleOf2);
                  }
              }
              return 1;
          }
      
          public static int getMaxSampleSize(int dim, int min, boolean multipleOf2){
              int add=multipleOf2 ? 2 : 1;
              int size=0;
              while(min<(dim/(size+add))){
                  size+=add;
              }
              size = size==0 ? 1 : size;
              return size;        
          }
      
          public static class Dimensions {
              int width;
              int height;
      
              public Dimensions(int width, int height) {
                  super();
                  this.width = width;
                  this.height = height;
              }
      
              @Override
              public String toString() {
                  return width+" x "+height;
              }
          }
      
          public static class Minimize {
              public enum Type {
                  WIDTH,HEIGHT,BOTH,MAX
              }
              Integer minWidth;
              Integer minHeight;
              Integer minDim;
              Type type;
      
              public Minimize(int min, Type type) {
                  super();
                  this.type = type;
                  switch(type){
                  case WIDTH:
                      this.minWidth=min;
                      break;
                  case HEIGHT:
                      this.minHeight=min;
                      break;
                  case BOTH:
                      this.minWidth=min;
                      this.minHeight=min;
                      break;
                  case MAX:
                      this.minDim=min;
                      break;
                  }
              }
      
              public Minimize(int minWidth, int minHeight) {
                  super();
                  this.type=Type.BOTH;
                  this.minWidth = minWidth;
                  this.minHeight = minHeight;
              }
      
          }
      
          /**
           * Estimates size of Bitmap in bytes depending on dimensions and Bitmap.Config
           * @param width
           * @param height
           * @param config
           * @return
           */
          public static long estimateBitmapBytes(int width, int height, Bitmap.Config config){
              long pixels=width*height;
              switch(config){
              case ALPHA_8: // 1 byte per pixel
                  return pixels;
              case ARGB_4444: // 2 bytes per pixel, but depreciated
                  return pixels*2;
              case ARGB_8888: // 4 bytes per pixel
                  return pixels*4;
              case RGB_565: // 2 bytes per pixel
                  return pixels*2;
              default:
                  return pixels;
              }
          }
      
          private static BitmapFactory.Options getOptionsForDimensions(){
              BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds=true;
              return options;
          }
      
          private static BitmapFactory.Options getOptionsForSampling(int sampleSize, Bitmap.Config bitmapConfig){
              BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds = false;
              options.inDither = false;
              options.inSampleSize = sampleSize;
              options.inScaled = false;
              options.inPreferredConfig = bitmapConfig;
              return options;
          }
      }
      
      import java.io.File;
      import java.io.FileInputStream;
      
      import android.graphics.Bitmap;
      import android.graphics.Bitmap.Config;
      import android.graphics.BitmapFactory;
      import android.graphics.Canvas;
      import android.graphics.Matrix;
      import android.graphics.drawable.BitmapDrawable;
      import android.graphics.drawable.Drawable;
      
      public class BitmapHelper
      {
      
          //decodes image and scales it to reduce memory consumption
          public static Bitmap decodeFile(File bitmapFile, int requiredWidth, int requiredHeight, boolean quickAndDirty)
          {
              try
              {
                  //Decode image size
                  BitmapFactory.Options bitmapSizeOptions = new BitmapFactory.Options();
                  bitmapSizeOptions.inJustDecodeBounds = true;
                  BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapSizeOptions);
      
                  // load image using inSampleSize adapted to required image size
                  BitmapFactory.Options bitmapDecodeOptions = new BitmapFactory.Options();
                  bitmapDecodeOptions.inTempStorage = new byte[16 * 1024];
                  bitmapDecodeOptions.inSampleSize = computeInSampleSize(bitmapSizeOptions, requiredWidth, requiredHeight, false);
                  bitmapDecodeOptions.inPurgeable = true;
                  bitmapDecodeOptions.inDither = !quickAndDirty;
                  bitmapDecodeOptions.inPreferredConfig = quickAndDirty ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;
      
                  Bitmap decodedBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapDecodeOptions);
      
                  // scale bitmap to mathc required size (and keep aspect ratio)
      
                  float srcWidth = (float) bitmapDecodeOptions.outWidth;
                  float srcHeight = (float) bitmapDecodeOptions.outHeight;
      
                  float dstWidth = (float) requiredWidth;
                  float dstHeight = (float) requiredHeight;
      
                  float srcAspectRatio = srcWidth / srcHeight;
                  float dstAspectRatio = dstWidth / dstHeight;
      
                  // recycleDecodedBitmap is used to know if we must recycle intermediary 'decodedBitmap'
                  // (DO NOT recycle it right away: wait for end of bitmap manipulation process to avoid
                  // java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@416ee7d8
                  // I do not excatly understand why, but this way it's OK
      
                  boolean recycleDecodedBitmap = false;
      
                  Bitmap scaledBitmap = decodedBitmap;
                  if (srcAspectRatio < dstAspectRatio)
                  {
                      scaledBitmap = getScaledBitmap(decodedBitmap, (int) dstWidth, (int) (srcHeight * (dstWidth / srcWidth)));
                      // will recycle recycleDecodedBitmap
                      recycleDecodedBitmap = true;
                  }
                  else if (srcAspectRatio > dstAspectRatio)
                  {
                      scaledBitmap = getScaledBitmap(decodedBitmap, (int) (srcWidth * (dstHeight / srcHeight)), (int) dstHeight);
                      recycleDecodedBitmap = true;
                  }
      
                  // crop image to match required image size
      
                  int scaledBitmapWidth = scaledBitmap.getWidth();
                  int scaledBitmapHeight = scaledBitmap.getHeight();
      
                  Bitmap croppedBitmap = scaledBitmap;
      
                  if (scaledBitmapWidth > requiredWidth)
                  {
                      int xOffset = (scaledBitmapWidth - requiredWidth) / 2;
                      croppedBitmap = Bitmap.createBitmap(scaledBitmap, xOffset, 0, requiredWidth, requiredHeight);
                      scaledBitmap.recycle();
                  }
                  else if (scaledBitmapHeight > requiredHeight)
                  {
                      int yOffset = (scaledBitmapHeight - requiredHeight) / 2;
                      croppedBitmap = Bitmap.createBitmap(scaledBitmap, 0, yOffset, requiredWidth, requiredHeight);
                      scaledBitmap.recycle();
                  }
      
                  if (recycleDecodedBitmap)
                  {
                      decodedBitmap.recycle();
                  }
                  decodedBitmap = null;
      
                  scaledBitmap = null;
                  return croppedBitmap;
              }
              catch (Exception ex)
              {
                  ex.printStackTrace();
              }
              return null;
          }
      
          /**
           * compute powerOf2 or exact scale to be used as {@link BitmapFactory.Options#inSampleSize} value (for subSampling)
           * 
           * @param requiredWidth
           * @param requiredHeight
           * @param powerOf2
           *            weither we want a power of 2 sclae or not
           * @return
           */
          public static int computeInSampleSize(BitmapFactory.Options options, int dstWidth, int dstHeight, boolean powerOf2)
          {
              int inSampleSize = 1;
      
              // Raw height and width of image
              final int srcHeight = options.outHeight;
              final int srcWidth = options.outWidth;
      
              if (powerOf2)
              {
                  //Find the correct scale value. It should be the power of 2.
      
                  int tmpWidth = srcWidth, tmpHeight = srcHeight;
                  while (true)
                  {
                      if (tmpWidth / 2 < dstWidth || tmpHeight / 2 < dstHeight)
                          break;
                      tmpWidth /= 2;
                      tmpHeight /= 2;
                      inSampleSize *= 2;
                  }
              }
              else
              {
                  // Calculate ratios of height and width to requested height and width
                  final int heightRatio = Math.round((float) srcHeight / (float) dstHeight);
                  final int widthRatio = Math.round((float) srcWidth / (float) dstWidth);
      
                  // Choose the smallest ratio as inSampleSize value, this will guarantee
                  // a final image with both dimensions larger than or equal to the
                  // requested height and width.
                  inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
              }
      
              return inSampleSize;
          }
      
          public static Bitmap drawableToBitmap(Drawable drawable)
          {
              if (drawable instanceof BitmapDrawable)
              {
                  return ((BitmapDrawable) drawable).getBitmap();
              }
      
              Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
              Canvas canvas = new Canvas(bitmap);
              drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
              drawable.draw(canvas);
      
              return bitmap;
          }
      
          public static Bitmap getScaledBitmap(Bitmap bitmap, int newWidth, int newHeight)
          {
              int width = bitmap.getWidth();
              int height = bitmap.getHeight();
              float scaleWidth = ((float) newWidth) / width;
              float scaleHeight = ((float) newHeight) / height;
      
              // CREATE A MATRIX FOR THE MANIPULATION
              Matrix matrix = new Matrix();
              // RESIZE THE BIT MAP
              matrix.postScale(scaleWidth, scaleHeight);
      
              // RECREATE THE NEW BITMAP
              Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
              return resizedBitmap;
          }
      
      }
      
      private Bitmap decodeFile(String fPath) {
          // Decode image size
          BitmapFactory.Options opts = new BitmapFactory.Options();
          /*
           * If set to true, the decoder will return null (no bitmap), but the
           * out... fields will still be set, allowing the caller to query the
           * bitmap without having to allocate the memory for its pixels.
           */
          opts.inJustDecodeBounds = true;
          opts.inDither = false; // Disable Dithering mode
          opts.inPurgeable = true; // Tell to gc that whether it needs free
                                      // memory, the Bitmap can be cleared
          opts.inInputShareable = true; // Which kind of reference will be used to
                                          // recover the Bitmap data after being
                                          // clear, when it will be used in the
                                          // future
      
          BitmapFactory.decodeFile(fPath, opts);
      
          // The new size we want to scale to
          final int REQUIRED_SIZE = 70;
      
          // Find the correct scale value. 
          int scale = 1;
      
          if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE) {
      
              // Calculate ratios of height and width to requested height and width
              final int heightRatio = Math.round((float) opts.outHeight
                      / (float) REQUIRED_SIZE);
              final int widthRatio = Math.round((float) opts.outWidth
                      / (float) REQUIRED_SIZE);
      
              // Choose the smallest ratio as inSampleSize value, this will guarantee
              // a final image with both dimensions larger than or equal to the
              // requested height and width.
              scale = heightRatio < widthRatio ? heightRatio : widthRatio;//
          }
      
          // Decode bitmap with inSampleSize set
          opts.inJustDecodeBounds = false;
      
          opts.inSampleSize = scale;
      
          Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy(
                  Bitmap.Config.RGB_565, false);
      
          return bm;
      
      }
      
      public static Bitmap decodeFile(File f)
      {
          Bitmap b = null;
          try
          {
              // Decode image size
              BitmapFactory.Options o = new BitmapFactory.Options();
              o.inJustDecodeBounds = true;
      
              FileInputStream fis = new FileInputStream(f);
              try
              {
                  BitmapFactory.decodeStream(fis, null, o);
              }
              finally
              {
                  fis.close();
              }
      
              // In Samsung Galaxy S3, typically max memory is 64mb
              // Camera max resolution is 3264 x 2448, times 4 to get Bitmap memory of 30.5mb for one bitmap
              // If we use scale of 2, resolution will be halved, 1632 x 1224 and x 4 to get Bitmap memory of 7.62mb
              // We try use 25% memory which equals to 16mb maximum for one bitmap
              long maxMemory = Runtime.getRuntime().maxMemory();
              int maxMemoryForImage = (int) (maxMemory / 100 * 25);
      
              // Refer to
              // http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
              // A full screen GridView filled with images on a device with
              // 800x480 resolution would use around 1.5MB (800*480*4 bytes)
              // When bitmap option's inSampleSize doubled, pixel height and
              // weight both reduce in half
              int scale = 1;
              while ((o.outWidth / scale) * (o.outHeight / scale) * 4 > maxMemoryForImage)
              scale *= 2;
      
              // Decode with inSampleSize
              BitmapFactory.Options o2 = new BitmapFactory.Options();
              o2.inSampleSize = scale;
              fis = new FileInputStream(f);
              try
              {
                  b = BitmapFactory.decodeStream(fis, null, o2);
              }
              finally
              {
                  fis.close();
              }
          }
          catch (IOException e)
          {
          }
          return b;
      }
      
      Resources res = getResources();
      WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
      Display display = window.getDefaultDisplay();
      @SuppressWarnings("deprecation")
      int width = display.getWidth();
      @SuppressWarnings("deprecation")
      int height = display.getHeight();
      try {
          if (bitmap != null) {
              bitmap.recycle();
              bitmap = null;
              System.gc();
          }
          bitmap = Bitmap.createScaledBitmap(BitmapFactory
              .decodeFile(ImageData_Path.get(img_pos).getPath()),
              width, height, true);
      } catch (OutOfMemoryError e) {
          if (bitmap != null) {
              bitmap.recycle();
              bitmap = null;
              System.gc();
          }
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inPreferredConfig = Config.RGB_565;
          options.inSampleSize = 1;
          options.inPurgeable = true;
          bitmapBitmap.createScaledBitmap(BitmapFactory.decodeFile(ImageData_Path.get(img_pos)
              .getPath().toString(), options), width, height,true);
      }
      return bitmap;
      
       <application
               android:largeHeap="true"