带位图的内存不足错误

时间:2013-05-27 03:23:13

标签: android android-canvas android-image

在运行时,我试图将图像放在表面视图中。当我尝试使用Drawable文件夹中的图像时出现内存不足错误。在stackoverflow中快速搜索后,我发现如果我们从资产文件夹访问图像会有一些缓解。但是我仍然在运行时遇到Out of memory错误。

我已经分析并发现缩放将有助于解决此类与内存相​​关的问题。问题是我的图像尺寸为1280 x 720,设备尺寸也相同。因此我觉得缩放不会有任何影响。

由于我们在这个社区有专家,如果您能帮助我提供一些解决此类问题的建议/示例,我将不胜感激。

场景1:

使用Drawable文件夹中的位图。

backgoundImage = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.backgroundhomepage), (int) dWidth, (int) dHeight, true);

    /***********************************************************************************************************************************************************
    1.  To get the image from asset library
     **************************************************************************************************************************************************************/ 

    public  Bitmap 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 bitmap;
    }

场景2:

使用Assets文件夹中的位图

backgoundImage = Bitmap.createScaledBitmap(getAssetImage(context,"backgroundhomepage"), (int) dWidth, (int) dHeight, true);

3 个答案:

答案 0 :(得分:3)

当您的应用超出堆中分配的内存时,会发生OutofMemory。位图太大而无法放入内存即堆中。在这种情况下,你的内存不足。您需要缩小位图然后使用相同的位图。为此,请检查以下链接

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

还有一个博客@ http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html(避免内存泄漏)

 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;
}

从文档引用

BitmapFactory类提供了几种解码方法(decodeByteArray(),decodeFile(),decodeResource()等),用于从各种源创建位图。根据图像数据源选择最合适的解码方法。这些方法尝试为构造的位图分配内存,因此很容易导致OutOfMemory异常。每种类型的解码方法都有其他签名,可让您通过BitmapFactory.Options类指定解码选项。

在解码时将inJustDecodeBounds属性设置为true可避免内存分配,为位图对象返回null但设置outWidth,outHeight和outMimeType。此技术允许您在构造(和内存分配)位图之前读取图像数据的尺寸和类型。

同时检查此链接以进行内存管理。

https://www.youtube.com/watch?v=_CruQY55HOk

答案 1 :(得分:2)

快速解决方案

# Plot
ggplot(NULL) +
  aes(x = Z$Track,
      y = Z$Position,
      fill = colors,
      label = letters) +
  geom_raster() +
  geom_text() +
  scale_fill_manual(values=my_fill)

在清单文件中输入appplication标签。

答案 2 :(得分:0)

您可以使用以下代码从文件中加载位图:

private Bitmap decodeFile(File f,int req_Height,int req_Width){
    try {
        //decode image size
        BitmapFactory.Options o1 = new BitmapFactory.Options();
        o1.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o1);


        //Find the correct scale value. It should be the power of 2.
        int width_tmp = o1.outWidth;
        int height_tmp = o1.outHeight;
        int scale = 1;

        if(width_tmp > req_Width || height_tmp > req_Height)
        {
             int heightRatio = Math.round((float) height_tmp / (float) req_Height);
             int widthRatio = Math.round((float) width_tmp / (float) req_Width);


             scale = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        o2.inScaled = false;
        return BitmapFactory.decodeFile(f.getAbsolutePath(),o2);
    } 
    catch(Exception e) 
    {
      e.printStackTrace();
    }
    return null;
}

它应该解决你的内存不足异常。 链接here详细解释了您的答案。