###前提・実現したいこと
WPFで画像閲覧ソフトを作成しています。
ListBox + UniformGridを使用し、指定された行・列数で分割し一覧そこに画像を順番に表示するものです。
###発生している問題・エラーメッセージ
「進む」ボタンを押すことにより、指定数分シフトして再表示しようとすると、
ImageConverterクラスの
var bmp = new WriteableBitmap(decoder.Frames[0]);で
System.Runtime.InteropServices.COMException が発生しました。 ErrorCode=-2003304445 HResult=-2003304445 Message=HRESULT からの例外:0x88980003 Source=PresentationCore StackTrace: 場所 System.Windows.Media.Imaging.WriteableBitmap.InitFromBitmapSource(BitmapSource source)
例外を無視してそのまま進めると、
var decoder = BitmapDecoder.Createメソッドのとこで、
System.OutOfMemoryException が発生しました。 HResult=-2147024882 Message=プログラムの実行を続行するための十分なメモリがありませんでした。 Source=PresentationCore StackTrace: 場所 System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap(BitmapFrame frame, BitmapSourceSafeMILHandle wicSource, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, BitmapPalette palette) InnerException:
が起こってしまいます。
メモリの解放がうまくいってないとは思うのですが、どこでどうしたら良いのか分からず煮詰まっています。
(根本的に考え方がおかしいのか?)
手掛かりになるようなヒントでも良いのでお知恵をお貸しください。
宜しくお願いいたします。
###該当のソースコード
XAML
1<Window x:Name="window" x:Class="WpfApplication19.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApplication19" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="600" Width="800"> 9 10 <Window.Resources> 11 <local:ImageConverter x:Key="ImageConverter"/> 12 </Window.Resources> 13 14 <Window.DataContext> 15 <local:MainWindowViewModel/> 16 </Window.DataContext> 17 18 <DockPanel> 19 <Button x:Name="NextButton" DockPanel.Dock="Top" Content="進む" Click="NextButton_Click" /> 20 21 <ListBox x:Name="listBox" ItemsSource="{Binding DisplayFileNameList}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden"> 22 <ListBox.ItemsPanel> 23 <ItemsPanelTemplate> 24 <UniformGrid Rows="{Binding SelectedRow}" Columns="{Binding SelectedCol}" 25 Width="{Binding ActualWidth, ElementName=listBox, Mode=OneWay}" 26 Height="{Binding ActualHeight, ElementName=listBox, Mode=OneWay}" /> 27 </ItemsPanelTemplate> 28 </ListBox.ItemsPanel> 29 <ListBox.ItemTemplate> 30 <DataTemplate> 31 <Border BorderThickness="1" BorderBrush="Black" HorizontalAlignment="Center" VerticalAlignment="Center"> 32 <DockPanel> 33 <TextBlock DockPanel.Dock="Bottom" Text="{Binding FileDateTIme}" /> 34 <Image Source="{Binding FullFileName, Converter={StaticResource ImageConverter}}" /> 35 </DockPanel> 36 </Border> 37 </DataTemplate> 38 </ListBox.ItemTemplate> 39 </ListBox> 40 41 </DockPanel> 42</Window> 43 44
C#
1 2public partial class MainWindow : Window 3{ 4 private MainWindowViewModel _viewModel = null; 5 private int startIndex = 0; 6 7 public MainWindow() 8 { 9 InitializeComponent(); 10 11 _viewModel = this.DataContext as MainWindowViewModel; 12 string pathName = @"E:\ImageFolder"; 13 foreach (string f in Directory.EnumerateFiles(pathName, "*.jpg", SearchOption.TopDirectoryOnly)) 14 { 15 _viewModel.FileNameList.Add(new ImageFileInfo() 16 { 17 FullFileName = f, 18 FileDateTIme = File.GetLastAccessTime(f) 19 }); 20 } 21 _viewModel.SetDisplayList(startIndex); 22 } 23 24 private void NextButton_Click(object sender, RoutedEventArgs e) 25 { 26 _viewModel.SetDisplayList(++startIndex); 27 } 28} 29 30public class MainWindowViewModel : INotifyPropertyChanged 31{ 32 public event PropertyChangedEventHandler PropertyChanged; 33 protected virtual void RaisePropertyChanged([CallerMemberName]string propertyName = null) 34 { 35 if (PropertyChanged != null) 36 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 37 } 38 39 public int SelectedRow { get { return 5; } } 40 public int SelectedCol { get { return 5; } } 41 42 private List<ImageFileInfo> _fileNameList = new List<ImageFileInfo>(); 43 public List<ImageFileInfo> FileNameList 44 { 45 get { return _fileNameList; } 46 set 47 { 48 _fileNameList = value; 49 RaisePropertyChanged(); 50 } 51 } 52 53 private IList<ImageFileInfo> _displayFileNameList = new ObservableCollection<ImageFileInfo>(); 54 public IList<ImageFileInfo> DisplayFileNameList 55 { 56 get { return _displayFileNameList; } 57 set 58 { 59 _displayFileNameList = value; 60 RaisePropertyChanged(); 61 } 62 } 63 64 public void SetDisplayList(int startIndex) 65 { 66 _displayFileNameList.Clear(); 67 int max = startIndex + SelectedCol * SelectedRow; 68 69 for(int i=startIndex; i<max; i++) 70 { 71 DisplayFileNameList.Add(FileNameList.ElementAtOrDefault(i)); 72 } 73 } 74} 75 76public class ImageFileInfo 77{ 78 public string FullFileName { get; set; } 79 public DateTime FileDateTIme { get; set; } 80} 81 82public class ImageConverter : IValueConverter 83{ 84 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 85 { 86 var path = (string)value; 87 88 try 89 { 90 using (var fs = new FileStream(path, FileMode.Open)) 91 { 92 var decoder = BitmapDecoder.Create( 93 fs, 94 BitmapCreateOptions.None, 95 BitmapCacheOption.OnLoad); 96 var bmp = new WriteableBitmap(decoder.Frames[0]); 97 bmp.Freeze(); 98 return bmp; 99 } 100 } 101 catch (Exception ex) 102 { 103 Console.WriteLine(ex.Message); 104 return null; 105 } 106 } 107 108 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 109 { 110 throw new NotImplementedException(); 111 } 112} 113
###補足情報(言語/FW/ツール等のバージョンなど)
Visual Studio 2015
C# WPF
.NET Framework 4.5.2

回答3件
あなたの回答
tips
プレビュー