Хобрук: Ваш путь к мастерству в программировании

Загрузка BitmapImage занимает много памяти в WP 8.1 RT

Я использую приложение Windows Phone 8.1 RT. Один из способов отобразить изображение после его чтения из файла — создать BitmapImage и установить его в качестве источника для элемента управления XAML Image.

Я использую следующий код, чтобы сделать то же самое. Изображение хранится в папке 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 (плюс любое увеличение служебной памяти), но профилирование памяти приложения говорит об обратном. Я вижу, что память стреляет до 320 MB, когда загружается изображение 40 MB.

  2. Если я использую DecodePixelHeight или DecodePixelWidth для экономии памяти, память все равно увеличивается до 50-80MB (больше, чем размер исходного изображения), в зависимости от значения DecodePixelHeight/DecodePixelWidth.

Я ожидаю, что ОС будет разумно использовать память и использовать минимальный объем памяти при загрузке изображений. Я ожидал, что ОС будет использовать менее 40 MB памяти, когда установлено DecodePixelWidth, но был очень удивлен, увидев фактические результаты.

Может кто-нибудь объяснить, почему при загрузке изображений в память используется такой большой объем памяти? Это ожидаемое поведение? Что я могу сделать для экономии памяти, потому что, если дела пойдут так, я не могу загрузить два больших изображения в память одновременно, не получая OOM, даже с DecodePixelWidth.

Скриншоты профилирования прилагаю.

  1. Без использования DecodePixelWidth размер изображения 40 MB. Первый пик 245 MB, второй пик 327 MB

введите здесь описание изображения

  1. Используется DecodePixelWidth = 500, размер изображения 40 MB. Первый пик — 88 MB, а устойчивый уровень — 49 MB.

введите здесь описание изображения


Ответы:


1

Вместо создания BitmapImage через IRandomAccesStream вы можете создать сжатую миниатюру из StorageFile.

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

Это создает BitmapImage, который значительно меньше обычного BitmapImage непосредственно из потока.

Кроме того, если вам нужно загрузить большой список изображений, вам следует обратиться к виртуализации или даже к добавочным спискам.

24.11.2015
  • Я не хочу показывать миниатюру; Я хочу загрузить изображение с высоким разрешением и отобразить его. 24.11.2015
  • В метод передаются три значения: ThumbnailMode, Requestedsize и ThumbnailOption. Я поставил запрошенный размер как 90, потому что мне просто не нужно отображать очень большие изображения, просто очень много. но все же в таком размере они смотрятся очень хорошо. Бьюсь об заклад, если вы посмотрите на эти значения, вы получите то, что вам нужно. С моим приложением я могу загрузить несколько сотен изображений высокого разрешения без каких-либо проблем с памятью. 24.11.2015
  • Новые материалы

    HMTL - Многозадачное обучение для решения задач НЛП
    Достижение результатов SOTA путем передачи знаний между задачами Область обработки естественного языка включает в себя десятки задач, среди которых машинный перевод, распознавание именованных..

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..