【发布时间】:2014-11-20 03:15:42
【问题描述】:
我必须同时显示约 150 张高分辨率图像(每张约 5 MB)。问题是同时加载所有这些图像需要大量时间。所以我想在开始时显示低分辨率图像,同时在背景中加载真正的高分辨率图像。然后当它们准备好时切换它们。
【问题讨论】:
标签: wpf image backgroundworker bitmapimage
我必须同时显示约 150 张高分辨率图像(每张约 5 MB)。问题是同时加载所有这些图像需要大量时间。所以我想在开始时显示低分辨率图像,同时在背景中加载真正的高分辨率图像。然后当它们准备好时切换它们。
【问题讨论】:
标签: wpf image backgroundworker bitmapimage
我不会为所有的 C# 代码而烦恼。相反,我只使用集合控件和文件路径集合。试试这个例子:
<ListBox ItemsSource="{Binding FilePaths}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="250" Stretch="Uniform" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
private ObservableCollection<string> filePaths = new ObservableCollection<string>();
public ObservableCollection<string> FilePaths
{
get { return filePaths; }
set { filePaths = value; NotifyPropertyChanged("FilePaths"); }
}
...
FilePaths = new ObservableCollection<string>(Directory.GetFiles(
Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "*.png"));
【讨论】:
一段时间后,我最终得到了这个解决方案。首先,我加载低分辨率图像并将它们添加到网格中:
foreach (var extElem in ElemList)
{
IdImage img = new IdImage();
img.Id = extElem.ImageID;
img.CollectionId = extElem.CollectionID;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(extElem.Url, UriKind.Absolute);
bi.DecodePixelWidth = 200; //If you want to further reduce the image size (and load time)
bi.EndInit();
img.Source = bi;
grid.Children.Add(img);
_imgList.Add(img);
}
然后我开始后台操作以加载高分辨率图像并更改位图的来源:
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += (s, args) =>
{
int i = 0;
foreach (var extElem in _imgList)
{
String url = extElem.HighResImageUri;
Image img = _imgList.ElementAt(i);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(url, UriKind.Absolute);
bi.EndInit();
bi.Freeze();
Dispatcher.BeginInvoke((Action)(() =>
{
img.Source = bi;
}));
}
i++;
}
bgw.RunWorkerAsync();
【讨论】:
MVVM。