Я загружаю изображения 240 штук в ListBox.
Но у меня этот процесс отнимает 1600 мб оперативной памяти и я никак не могу освободить эту память. Другие программы, как к примеру Nvidia Geforce Experience показывает все картинки и оперативную память больше 10-15 мб не занимает
Каким образом можно реализовать показ картинок в папке?
Разметка Xaml
<ListBox x:Name="ListBox_Screenshots"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemContainerStyle="{DynamicResource ListBoxItem_Style}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
Margin="70,10,70,45" Background="#4DFFFFFF" BorderThickness="2,1"
SelectionMode="Extended" BorderBrush="#FF21AFE4"
SelectionChanged="ListBox_Screenshots_SelectionChanged"
MouseDoubleClick="ListBox_Screenshots_MouseDoubleClick">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="240" ItemWidth="390"
Orientation="Horizontal" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="20" HorizontalAlignment="Center">
<Viewbox>
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding imgSource}"
CacheOption="OnLoad"/>
</Image.Source>
<Image.Effect>
<DropShadowEffect ShadowDepth="2"
BlurRadius="50"
Color="#FF00249C"/>
</Image.Effect>
</Image>
</Viewbox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Логика C#
//Загружаем все изображения
private void Screenshots_LoadAll()
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+ @"\GTA San Andreas User Files\SAMP\screens";
var dirs = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".png") || s.EndsWith(".jpg"));
foreach (string dir in dirs)
{
ListBox_Screenshots.Items.Add(new ImageScreen() { imgSource = dir });
}
//Запускаем функцию на ожидание создания или удаления файлов
Screenshots_StartWatch(path);
}
//Смотрим на создание или удаления файла
private void Screenshots_StartWatch(string path)
{
FileSystemWatcher watch = new FileSystemWatcher();
watch.Path = path;
watch.Created += new FileSystemEventHandler(Screenshots_OnCreated);
watch.Deleted += new FileSystemEventHandler(Screenshots_OnDeleted);
watch.EnableRaisingEvents = true;
bIsScreenshotsWatching = true;
}
public class ImageScreen :IDisposable
{
public string imgSource { get; set; }
public void Dispose()
{
imgSource = null;
}
}
Для того чтобы не заморачиваться с созданием миниатюр, сначала рекомендую попробовать воспользоваться штатными средствами WPF.
Класс BitmapImage имеет ряд свойств предназначенных для этого, в частности DecodePixelWidth и DecodePixelHeight
Например, добавление одной строчки:
<ListBox ItemsSource="{Binding Images}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="240"
ItemWidth="240"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding}"
CacheOption="OnLoad"
DecodePixelHeight="240"/> <!--Обратите внимание на эту строку-->
</Image.Source>
</Image>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Позволило снизить потребление ОЗУ на стандартных обоинах Windows 7 с ~440 до ~95 МБ, причем приложение вообще без картинок занимает ~65 МБ.
До:
После:
Продвижение своими сайтами как стратегия роста и независимости