我试图显示(在具有自定义DataTemplate的ListBox中)从多页Tiff图像中提取的一系列BitmapSource框架(缩略图)。当我在UI线程上处理tiff,并直接将图像添加到列表框的项目集合或将它们添加到绑定的ObservableCollection时,它们在列表中显示正常。然而,试图异步加载每个缩略图(或者使用的BackgroundWorker或使用异步任务)的时候,我看到的行为我不能工作了:如预期异步加载时不出现在WPF窗体上的图像
- 第一缩略图加载
- 下,和所有后续缩略图获得列表中的项目(我看到了边框),但所有显示的都是空白图像。它显示正确的项目数量,但在第一个之后没有图像。
我玩过试图冻结缩略图(不行),尝试将它们发送回UI线程并通过工作人员的ReportProgress将它们添加到集合中(但不行),但我可以似乎没有让他们表现出来。
工作UI线程(其中SyncImages是绑定到我的列表框一个ObservableCollection和OnPropertyChanged处理通知事件):
private void LoadSynchronous()
{
Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
foreach (var frame in decoder.Frames)
{
//frame.Freeze(); //Tried this but no effect.
SyncImages.Add(frame);
}
OnPropertyChanged("SyncImages");
}
不工作(这个例子中直接添加帧到列表中,但我我也尝试通过绑定结果没有任何区别):
private void LoadAsync(object sender, DoWorkEventArgs e)
{
Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
foreach (var frame in decoder.Frames)
{
// frame.Freeze();
(sender as BackgroundWorker).ReportProgress(0, frame);
}
OnPropertyChanged("AsyncImages");
}
private void ReportAsyncProgress(object send, ProgressChangedEventArgs e)
{
var frame = (BitmapSource) e.UserState;
LbAsynchronous.Items.Add(frame);
}
希望有人可以对这里发生的事情有所了解。我知道代码可以提取框架,所以即使在异步示例中它们也必须加载,但看起来好像UI线程无法访问保存图像数据以在窗体上显示它们的源的属性(这就是为什么我试图冻结)。
任何想法,将不胜感激!
示例图像:从他原来的问题评论http://i.imgur.com/75wMkmS.png
不知道为什么冻结不能正常工作,你可以看一些其他的建议在这里:http://stackoverflow.com/questions/3034902/怎么做 - 你从背景线程到线程 - UI-thread-in-wpf – vesan
感谢您的链接 - 我一直在检查这些建议,看看是否有任何结果它。我附上了一张图片,希望能引发一个推荐:http://i.imgur.com/75wMkmS.png左边是UI线程处理结果,右边是BackgroundWorker/async版本。 –
你正在关闭FileStream吗?为了确保立即加载所有帧,并且可以在创建BitmapFrame后立即关闭流,应该设置“BitmapCacheOption.OnLoad”而不是“Default”。 – Clemens