1

我正在使用Windows Phone 8.1 RT应用程序。从文件中读取图像后显示图像的一种方法是创建一个BitmapImage并将其设置为XAML控件的源。加载BitmapImage在WP 8.1中占用大量内存RT

我正在使用下面的代码来做同样的事情。图像存储在LocalFolder

private async void LoadImage() 
{ 
    StorageFolder folder = ApplicationData.Current.LocalFolder; 
    StorageFile file = await folder.GetFileAsync("imageFile.jpg"); 

    BitmapImage bitmapImage = new BitmapImage(); 

    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read)) 
    { 
     bitmapImage.DecodePixelWidth = 500; 
     await bitmapImage.SetSourceAsync(stream); 
    } 

    imageHolder.Source = bitmapImage; 
} 

由于我加载图像的一小部分,我用的是DecodePixelWidth以节约内存。但是,我的观察结果并不符合预期。

观察:

  1. 如果我一个40 MB图像加载到内存中,由应围绕40 MB(加上任何开销内存增加)增加对内存的占用,但应用程序的内存分析说,否则。我看到当加载一张40 MB图像时,内存拍到320 MB

  2. 如果我使用DecodePixelHeightDecodePixelWidth以节省存储器,所述存储器仍然拍摄高达50-80MB(比原始图像的尺寸大),这取决于DecodePixelHeight/DecodePixelWidth的值。

我希望操作系统明智地使用内存,并在加载图像时使用最少量的内存。我预计在设置DecodePixelWidth时,操作系统的内存使用量低于40 MB,但看到实际结果时非常惊讶。

有人可以解释为什么在将图像加载到内存时使用如此大量的内存?这是预期的行为?我可以做些什么来节省内存,因为如果事情是这样,即使使用DecodePixelWidth,我也无法同时将两个大图像加载到内存中,而无法获得OOM。

连接了剖析屏幕截图。

  1. 不使用DecodePixelWidth,图像尺寸40 MB.第一峰是245 MB,第二个峰是327 MB

enter image description here

  • 使用DecodePixelWidth = 500,图像尺寸40 MB。第一峰88 MB,并持续水平49 MB
  • enter image description here

    回答

    1

    而是通过IRandomAccesStream创建的BitmapImage可以从StorageFile创建压缩缩略图的。

    StorageItemThumbnail thumb = file.GetScaledImageAsThumbnailAsync(ThumbnailMode.ListView, 
                        90, 
                        ThumbnailOptions.UseCurrentScale); 
         var bitmap = new BitmapImage(); 
         bitmap.SetSource(thumb); 
    

    这会创建一个比直接从一个流中的普通BitmapImage小得多的BitmapImage。

    此外,如果您需要加载大量图像,您应该查看虚拟化甚至增量列表。

    +0

    我不想显示缩略图;我想加载一个高分辨率的图像并显示它。 – Flipper

    +1

    传递给该方法的三个值是ThumbnailMode,Requestedsize和ThumbnailOption。我把所需的尺寸设置为90,因为我不需要显示非常大的图像,只是非常多。但仍然在这个尺寸,他们看起来非常好。我敢打赌,如果你看看这些价值观,你会得到你所需要的。使用我的应用程序,我可以加载数百个高分辨率图像,而不会对内存造成任何问题。 – StijnvanGaal