Xamarin:Android - 带有大位图的OutOfMemory异常 - 如何解决?

时间:2016-02-07 14:11:56

标签: c# android xamarin xamarin.android android-bitmap

我正在拍摄图像,解码byte array方法生成的TakePicture,然后旋转bitmap 270度。问题是我似乎耗尽了内存,我不知道如何解决它。这是代码:

Bitmap image = BitmapFactory.DecodeByteArray (data, 0, data.Length);
data = null;
Bitmap rotatedBitmap = Bitmap.CreateBitmap (image, 0, 0, image.Width,
    image.Height, matrix, true);

1 个答案:

答案 0 :(得分:2)

请查看官方Xamarin文档中的Load Large Bitmaps Efficiently,其中介绍了如何将大图像加载到内存中,而不会让应用程序通过在内存中加载较小的子采样版本来抛出OutOfMemoryException

读取位图尺寸和类型

async Task<BitmapFactory.Options> GetBitmapOptionsOfImageAsync()
{
    BitmapFactory.Options options = new BitmapFactory.Options
    {
        InJustDecodeBounds = true
    };

    // The result will be null because InJustDecodeBounds == true.
    Bitmap result=  await BitmapFactory.DecodeResourceAsync(Resources, Resource.Drawable.someImage, options);

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

    _originalDimensions.Text = string.Format("Original Size= {0}x{1}", imageWidth, imageHeight);

    return options;
}

将缩小版本加载到内存

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

    if (height > reqHeight || width > reqWidth)
    {
        int halfHeight = (int)(height / 2);
        int halfWidth = (int)(width / 2);

        // Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway.
        while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
        {
            inSampleSize *= 2;
        }
    }

    return (int)inSampleSize;
}

将图像加载为异步

public async Task<Bitmap> LoadScaledDownBitmapForDisplayAsync(Resources res, BitmapFactory.Options options, int reqWidth, int reqHeight)
{
    // Calculate inSampleSize
    options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.InJustDecodeBounds = false;

    return await BitmapFactory.DecodeResourceAsync(res, Resource.Drawable.someImage, options);
}

并将其命名为加载图片,例如OnCreate

protected async override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);
    _imageView = FindViewById<ImageView>(Resource.Id.resized_imageview);

    BitmapFactory.Options options = await GetBitmapOptionsOfImageAsync();
    Bitmap bitmapToDisplay = await LoadScaledDownBitmapForDisplayAsync (Resources, 
                             options, 
                             150,  //for 150 X 150 resolution
                             150);
    _imageView.SetImageBitmap(bitmapToDisplay);
}

希望它有所帮助。