Xamarin Forms Android display pictures throws Exception

1k Views Asked by At

Showing multiple pictures from a gallery within a page throws an exception. Displaying one photo with a resolution (e.g 3264x2488) on one page works. But when it comes to display more than one with a high resolution it crashes on Android. The higher the resolution the less can be displayed on a page.

https://github.com/Crunch91/RezepteTagebuch/blob/master/RezepteTagebuch/RezepteTagebuch/Views/RecipeView.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="RezepteTagebuch.Views.RecipeView">
    <...>
    <StackLayout HorizontalOptions="Fill" Orientation="Horizontal">
      <Image Source="{Binding FoodPicture}"/>
      <Image Source="{Binding DescriptionPicture}"/>
    </StackLayout>
    </...>

I can see the same behaviour in my ListView. One photo in the ListView works well. Once I add another photo it crashes again.

https://github.com/Crunch91/RezepteTagebuch/blob/master/RezepteTagebuch/RezepteTagebuch/Views/AllRecipeView.xaml

<StackLayout>   
  <ListView ItemsSource="{Binding Recipes}" x:Name="recipeList">    
    <...>
    <ViewCell>
      <StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal">
            <Image WidthRequest="44" HeightRequest="44" Source="{Binding FoodPicturePath}" />              
      </StackLayout>
    </ViewCell>
    </...>
  </ListView>
</StackLayout>

This is my repo where you can find my running Xamarin Forms application:

https://github.com/Crunch91/RezepteTagebuch

I'm debugging on a Samsung Galaxy S3 with Android 4.3

I would be appreciated if someone could help.

UPDATE:

@idoT was right. I get an "OutOfMemoryException".

What's the best way to resize the image before it's displayed?

1

There are 1 best solutions below

1
On

There is a great article on Android Developers how to load large bitmaps efficiently:

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

Ideally you would release the memory for every picture that is not shown on screen to free up resources.