Модераторы: gambit, Kefir, Partizan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> оптимизация загрузки картинок 
:(
    Опции темы
San4o_Pan4o
Дата 6.3.2009, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



В общем такая проблема: в ListView хочу показывать картинки. Опрашиваю какую-нить директорию на файлы *.jpg и их потом показываю как айтемы в ListView. Проблема в том, что если картинок много, оперативка кушается со зверским аппетитом.. Может кто-то сталкивался и поборол такое?
PM MAIL   Вверх
dazy
Дата 6.3.2009, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 15.9.2006

Репутация: 3
Всего: 8



Картинки меняют размер?
На диске у наверно 800х600, а в ListView 50х50 так?
PM MAIL   Вверх
San4o_Pan4o
Дата 6.3.2009, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



картинки на диске большие, да. Тут два варианта: либо грузить их полными, но в визуальном контейнере уменьшать, либо грузить их маленькими, задавая PixelDecodeWidth или PixelDecodeHeight. В обоих вариантах объем оперативки линейно растет от числа картинок. Просто во втором случае он меньше, чем в первом, но все же это проблема.. VirtualizingStackPanel не решает проблему, он удаляет визуальные контейнеры по мере их выхода из области видимости, но не чистит эти картинки из кэша.. Может есть штатный механизм для работы с памятью по принципу Recycling'а? Или идеи/примеры по реализации нештатного?
PM MAIL   Вверх
San4o_Pan4o
Дата 7.3.2009, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



есть у кого-нибудь идеи хотя бы?
PM MAIL   Вверх
knox
Дата 7.3.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 1.12.2007

Репутация: нет
Всего: нет



что за картинки (разрешение) и сколько занимают памяти, и сколько штук ?
PM MAIL   Вверх
-Mikle-
Дата 7.3.2009, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Можно использовать событие VirtualizingStackPanel.CleanUpVirtualizedItem. Оно вызывается для каждого элемента отдельно при очистке. Только я не смог добраться до самого Image, так как он у меня в DataTemplate. Наверняка это как-то просто и кто-то из форумчан знает как. Я это чувствую!!!  smile 

Вот мой код XAML:
Код

    <Grid xmlns:io="clr-namespace:System.IO;assembly=mscorlib">
        <Grid.Resources>
            <ObjectDataProvider x:Key="imagesFolder" ObjectType="{x:Type io:DirectoryInfo}" MethodName="GetFiles">
                <ObjectDataProvider.ConstructorParameters>C:\pics\</ObjectDataProvider.ConstructorParameters>
                <ObjectDataProvider.MethodParameters>*.jpg</ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>

            <DataTemplate x:Key="listViewItemImageTemplate">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding FullName}" Width="100" Margin="10,2" />
                    <StackPanel>
                        <TextBlock Text="{Binding Name}" FontWeight="Bold" />
                        <Rectangle Stroke="Black" StrokeThickness="1" Height="0.5" Margin="0,0,0,12" />
                        <TextBlock Text="{Binding CreationTime, StringFormat=d MMM yyy - tt hh:mm}" FontStyle="Italic" />
                        <TextBlock Text="{Binding Length, StringFormat=Размер: ### ### bytes}" FontStyle="Italic" />
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </Grid.Resources>

        <ListView ItemsSource="{Binding Source={StaticResource imagesFolder}}"
                  VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.CleanUpVirtualizedItem="listView1_CleanUpVirtualizedItem"
                  ItemTemplate="{StaticResource listViewItemImageTemplate}"  Margin="20" Name="listView1" />
    </Grid>


и обработчик:
Код

        private void listView1_CleanUpVirtualizedItem(object sender, CleanUpVirtualizedItemEventArgs e)
        {
            System.Diagnostics.Debug.Print("Cleaned: " + e.Value.ToString());

            // e.UIElement - ссылается на ListViewItem
            // e.Value     - на FileInfo(в моем случае)
            e.Handled = true;
        }


Осталось только добраться до Image и грохнуть Bitmap!!!  smile 


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Partizan
Дата 7.3.2009, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



До Image, возможно, получится добраться, используя Logical-/VisualTreeHelper


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
San4o_Pan4o
Дата 10.3.2009, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



ну чё-то поколдовал... не очень выходит..  Partizan, а можно поподробнее про Logical-/VisualTreeHelper? Проблема становится актуальнее, т.к. если начать менять, например, размер контейнеров динамически (дергать бегунок), то по будут перерисовываться 2000 картинок вне поля зрения можно поседеть.. Че мог, перепробовал..
PM MAIL   Вверх
-Mikle-
Дата 10.3.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Ты хоть бы что-то сказал про то, как ты сами картинки грузишь.
DataTemplate? Image? Кодом? Или как?

Может быть тебе свой контрол сделать, наследованный от Image или от FrameworkElement? Ничего не понятно... что-нить расскажи о том, как ты делаешь...

У DataTemplate есть метод FindName может оно тебе поможет в обработчике события который я показывал выше.

Есть еще:
Код

            RenderOptions.SetCachingHint(...);
            RenderOptions.SetCacheInvalidationThresholdMinimum(...);
            RenderOptions.SetCacheInvalidationThresholdMaximum(...);

или
Код

<element RenderOptions.CachingHint="..." RenderOptions.CacheInvalidationThresholdMinimum="..."  RenderOptions.CacheInvalidationThresholdMaximum="..." />

Задающие параметры кэша и его реинициализации при масштабировании.

Поскольку в WPF данные отделены от их представления (кнопка может иметь дерево вложенных объектов рисования), то может понадобится доступ к такому визуальному дереву. Статический класс VisualTreeHelper имеет набор методов для доступа к дереву Visual-объектов. 
LogicalTreeHelper - дает доступ к логическому дереву.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
San4o_Pan4o
Дата 10.3.2009, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



Итак, рассказываю. Сначала было тупое кодирование: т.е. на форме ListView, потом опрос какой-нибудь директории на наличие *.jpg и для каждого создание визуального контейнера (StackPanel с имэджэм и подписью). Потом решил отказаться от этого и сделал через ObjectDataProvider и DataTemplate's на основе какого-то из примеров MSDN + мои модификации.
Код

<ObjectDataProvider x:Name="PhotosODP" x:Key="MyPhotos" ObjectType="{x:Type l:PhotoList}"/>
<DataTemplate DataType="{x:Type l:Photo}">
            <StackPanel Width="{Binding ElementName=Zoomer, Path=Value}">
                    <Image Source="{Binding Source, Converter={StaticResource LocalUriToImageConverter}}" />
                    <TextBlock Foreground="White" Text="Photo" />
             </StackPanel>
</DataTemplate>
<ListView x:Name="MainViewer" ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="True" 
                  VirtualizingStackPanel.VirtualizationMode="Recycling" 
                  ItemsSource="{Binding Source={StaticResource MyPhotos}}">
            <ListView.View>
                <l:TileView />
            </ListView.View>
</ListView>

А вот классы фоток:
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Components
{
    public class Photo
    {
        public Photo(string path)
        {
            _source = path;
        }

        public override string ToString()
        {
            return Source;
        }

        private string _source;
        public string Source { get { return _source; } }

    }

    public class PhotoList : ObservableCollection<Photo>
    {
        public PhotoList() { }

        public PhotoList(string path) : this(new DirectoryInfo(path)) { }

        public PhotoList(DirectoryInfo directory)
        {
            _directory = directory;
            Update();
        }

        public string Path
        {
            set
            {
                _directory = new DirectoryInfo(value);
                Update();
            }
            get { return _directory.FullName; }
        }

        public DirectoryInfo Directory
        {
            set
            {
                _directory = value;
                Update();
            }
            get { return _directory; }
        }

        private void Update()
        {
            foreach (FileInfo f in _directory.GetFiles("*.jpg"))
            {
                Add(new Photo(f.FullName));
            }
        }

        DirectoryInfo _directory;
    }

}


Это сообщение отредактировал(а) San4o_Pan4o - 10.3.2009, 18:48
PM MAIL   Вверх
San4o_Pan4o
Дата 13.3.2009, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



Еще хотелось бы ускроить загрузку приложения. тут такой момент: при запуске сплэш-скрин висит и растет память, на ~300 5Мп фотках она ползет где-то до 150 метров, потом падает до 80 и стабилизируется, в этот же момент само приложение показывается. Вот это ползание как можно устранить? Т.е. сначала просто загрузить только те картинки, что в области видимости при старте, а потом по требованию остальные грузить
PM MAIL   Вверх
San4o_Pan4o
Дата 15.3.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



где же Вы, гуру?..
PM MAIL   Вверх
-Mikle-
Дата 15.3.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Есть одна задумка. Часов через 7-8 буду дома, напишу...


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Partizan
Дата 15.3.2009, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Цитата

Вот это ползание как можно устранить? Т.е. сначала просто загрузить только те картинки, что в области видимости при старте, а потом по требованию остальные грузить

 
Можно наверное....если использовать VirtualizingPanel


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
San4o_Pan4o
Дата 16.3.2009, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



Цитата

Можно наверное....если использовать VirtualizingPanel 

не помогает, везде где только можно ее включил - не полегчало:(
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.1004 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.