locked
BitmapImage.SetSourceAsync cost memory much more than BitmapImage.UriSource

    Question

  • As your know, The Image.Source can not set to local file path directly such as "D:\Images\1.jpg" in Windows Store app. I can only use the BitmapImage.SetSourceAsync to load these picture and I get into trouble of hight memory cost.

    Now, I have a picture "1.jpg" which size is 1.17MB in project, and the only one page:

    <Page
        x:Class="ImageMemoryCostTest.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:ImageMemoryCostTest"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Image x:Name="ImageHost" Visibility="Visible"/>
        </Grid>
    </Page>

    When I load the picture with this code in OnNavigatedTo method:

    protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                BitmapImage bitmap = new BitmapImage();
                bitmap.UriSource = new Uri("ms-appx:///../Assets/1.jpg");
                ImageHost.Source = bitmap;
            }

    The app run with 13MB memory cost. It seems right.

    But when I load picture with this code in OnNavigatedTo method:

    protected async override void OnNavigatedTo(NavigationEventArgs e)
            {
                var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///../Assets/1.jpg"));
                using (var s = await file.OpenReadAsync())
                {
                    var bitmap = new BitmapImage();
                    await bitmap.SetSourceAsync(s);
                    ImageHost.Source = bitmap;
                }
            }
    The app run with 23.6MB memory cost!! What's happend? How can I get around this issue?


    • Edited by lzptimeless Thursday, July 17, 2014 7:22 AM
    Thursday, July 17, 2014 7:21 AM

All replies

  • You probably loaded a number of libraries which are necessary to load the image.  Also, you may not have performed GC yet.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, July 17, 2014 7:18 PM
    Moderator
  • Thanks for reply, I have tried this:

     var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///../Assets/1.jpg"));
                using (var s = await file.GetThumbnailAsync(ThumbnailMode.SingleItem,1680))
                {
                    var bitmap = new BitmapImage();
                    await bitmap.SetSourceAsync(s);
                    ImageHost.Source = bitmap;
                }
                GC.Collect();

    But no use. And this issue is not caused by BitmapImage.SetSourceAsync need loaded more libraries I thought, Because I have made a statistic:

    1 image  load by SetSourceAsync: 23.6MB
    2 images load by SetSourceAsync: 29.4MB
    3 images load by SetSourceAsync: 35.9MB
    4 images load by SetSourceAsync: 55.1MB

    1 image  load by UriSource: 13.2MB
    2 images load by UriSource: 14.5MB
    3 images load by UriSource: 15.8MB
    4 images load by UriSource: 16.9MB

    Obviously, The SetSourceAsync way eat memory much more than UriSource way

    Friday, July 18, 2014 5:53 AM