当前位置: 首页 > 知识库问答 >
问题:

BitmapFactory.DecodeByteArray导致生长堆(frag情况)

公冶浩慨
2023-03-14

我正在用Xamarin开发一个Android应用程序。我在从字流生成图像方面遇到了问题。BitmapFactory(似乎是最流行的解决方案)正在引发巨大的分配问题--Grow堆。

        ConnectToDb connect = new ConnectToDb ();
        byte[] arr = connect.SelectImgByte(3,"Thea");

        BitmapFactory.Options options=new BitmapFactory.Options();
        options.InJustDecodeBounds = true;
        bmp = BitmapFactory.DecodeByteArray (arr, 0, arr.Length/*,options*/);
        _imageView.SetImageBitmap (bmp);
Thread started: <Thread Pool> #6
[dalvikvm-heap] Grow heap (frag case) to 22.596MB for 1997584-byte allocation
[Choreographer] Skipped 129 frames!  The application may be doing too much work on its main thread.
[dalvikvm-heap] Grow heap (frag case) to 20.755MB for 1997584-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 22.735MB for 1997584-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 24.710MB for 1997584-byte allocation

共有1个答案

许鸿志
2023-03-14

我看到的第一件事是使用injustdecodebounds,它通常用于获取图像的宽度和高度,如下所示:

var options = new BitmapFactory.Options {
    InJustDecodeBounds = true,
};
using (var derp = BitmapFactory.DecodeResource(Resources, 
    Resource.Id.myimage, options)) { }

var imageHeight = options.OutHeight;
var imageWidth  = options.OutWidth;

这通常用于获取图像的纵横比,然后再将其缩放,而不是将一个巨大的图像加载到内存中。

如果您看一下Xamarin文档中关于高效加载大位图的文档,您会发现他们正是为了这个目的才使用它的。

using(var bmp = DecodeBitmap(some args))
    imageView.SetImageBitmap(bmp);
using(var bmp = DecodeBitmap(some args)) {
    imageView.SetImageBitmap(bmp);
    bmp.Recycle();
}

因此,您需要执行类似的操作,可能还需要使用byte数组,因为它包含图像的所有像素。

因此,使用文档中的模式,您可以执行如下操作:

byte[] arr = connect.SelectImgByte(3,"Thea");

using(var bmp = DecodeSampledBitmapFromArray(arr, scaledWidth, scaledHeight)) {
    _imageView.SetImageBitmap(bmp);
    bmp.Recycle();
}

public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
    // Raw height and width of image
    var height = (float)options.OutHeight;
    var width = (float)options.OutWidth;
    var inSampleSize = 1D;

    if (height > reqHeight || width > reqWidth)
    {
        inSampleSize = width > height
                            ? height/reqHeight
                            : width/reqWidth;
    }

    return (int) inSampleSize;
}

public static Bitmap DecodeSampledBitmapFromArray(byte[] pixels, int reqWidth, int reqHeight)
{
    var options = new BitmapFactory.Options {
        InJustDecodeBounds = true,
    };
    using (var dispose = BitmapFactory.DecodeResource(arr, 0, arr.Length, options)) { }

    // Calculate inSampleSize
    options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.InJustDecodeBounds = false;
    return BitmapFactory.DecodeResource(arr, 0, arr.Length, options);
}
 类似资料:
  • 我有一个pageOffscreenPageLimit设置为1的ViewPager(共3页)。我用它为每页显示4个位图。位图是异步加载的,按比例缩小,以及所有这些东西,以避免OutOfMemory异常。我注意到由于GC导致的页面滚动出现了一些“停顿”,这里有一段日志: 堆大小保持在24MB并且不会增长。此外,在destroyItem中,我尝试释放ImageView,将drawables和回调设置为n

  • 对此有什么建议吗?我做错了什么?为什么不能帮助我减少字节分配?

  • 我在从4X设备上传视频时遇到了问题。我知道在samsung S2中只有15秒的vedio重新编码将创建一个30 mb的文件,但当我试图在php服务器上首先上传视频时,它显示了如下消息:d/dalvikvm(7638):GC_FOR_ALLOC释放263K,9%空闲12838K/14087K,暂停13ms,总计13ms I/dalvikvm-heap(7638):Grow heap(frag情况)到

  • 问题内容: 这有效:http : //play.golang.org/p/-Kv3xAguDR。 这导致堆栈溢出:http : //play.golang.org/p/1-AsHFj51O。 我不明白为什么。在这种情况下,使用接口的正确方法是什么? 问题答案: 这个 将呼叫您的,依次呼叫,等等。如果您需要解组JSON然后对其进行处理,那么一种巧妙的技术是声明一个本地类型,将数据解组到其中,然后转换

  • FRAG Framework for Rather Awesome Games Home page and installation instructions FRAG is a game creation framework being developed using the Nim programming language, and is currently in pre-alpha stat

  • 我的应用程序有问题。我的活动由以下xml代码组成: 使用充气,插入包含images.png!这会导致堆增长(frag情况)。是否有一种方法可以减少或增加堆,并保持此设置? 这是在Mainactive中插入的布局: 谢啦!