WPF/BackgroundWorker和位图源问题
我是WPF的初学者,正在尝试一个家庭项目来熟悉这项技术。我有一个简单的表单,用户选择一个图像文件,然后显示EXIF数据和图像的缩略图。这很好,但当我选择一个原始图像文件(~9 MB)时,在加载thumb时可能会有一点延迟,因此我认为可以使用BackgroundWorker对图像进行解码,用户可以查看EXIF数据,然后在图像解码后显示 BitmapSource对象在BackgroundWorkers DoWork方法中声明:WPF/BackgroundWorker和位图源问题,wpf,backgroundworker,bitmapsource,Wpf,Backgroundworker,Bitmapsource,我是WPF的初学者,正在尝试一个家庭项目来熟悉这项技术。我有一个简单的表单,用户选择一个图像文件,然后显示EXIF数据和图像的缩略图。这很好,但当我选择一个原始图像文件(~9 MB)时,在加载thumb时可能会有一点延迟,因此我认为可以使用BackgroundWorker对图像进行解码,用户可以查看EXIF数据,然后在图像解码后显示 BitmapSource对象在BackgroundWorkers DoWork方法中声明: worker.DoWork += delegate(object s,
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
string filePath = args.Argument as string;
BitmapDecoder bmpDecoder = BitmapDecoder.Create(new Uri(filePath), BitmapCreateOptions.None, BitmapCacheOption.None);
BitmapSource bmpSource = bmpDecoder.Frames[0];
bmpSource.Freeze(); //As suggested by Paul Betts
args.Result = bmpSource;
};
我遇到的问题是,当我尝试在RunWorkerCompleted方法中设置图像控件的源时,我收到一个错误,因为该对象属于另一个线程
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
imgThumb.Source = args.Result as BitmapSource;
};
我尝试使用imgThumb.Dispatcher.BeginInvoke()
方法设置源代码,但这也不起作用,我想这是因为另一个线程拥有args.Result
,而不是imgThumb
?我怎样才能避开这件事
这可能是因为我对调度器的编码错误(下面是从内存中删除的内容)
imgThumb.Dispatcher.Invoke(新操作(
委托(BitmapSource src)
{
imgThumb.Source=src;
}
),bmpSource);
欢迎提出任何建议或想法
更新
将我的DoWork方法更改为使用BitmapCreateOptions.None而不是.DelayCreation,但现在我在加载原始文件时遇到以下错误(到目前为止,我只测试了Canon.CR2文件),该代码对于jpg来说运行良好。这可能是因为我安装的佳能编解码器允许我显示原始文件的问题吗
应用程序调用了一个接口
这是为另一个目的而安排的
线(HRESULT的例外情况:
0x8001010E(RPC_E_错误_线程))
在BitmapSource上调用Freeze(),您就不会遇到这个问题(冻结消除了线程限制,但使对象不可变)我正好遇到了示例问题,幸运地解决了它 简短回答:换行
WriteableBitmap
。你,这代价很小
.在设置BitmapSource值之后,我在DoWork方法中添加了Freeze()调用。然后,我向RunWorkerCompleted方法添加以下行:BitmapSource xx=args.Result;这给了我和以前一样的错误。我遗漏了什么明显的东西吗?我已经用调度器删除了所有代码。我以前是个笨蛋,但现在有了一个不同的错误,更新了的问题。即使在很多年之后。非常感谢你。我一直在网络上寻找我的案子,这是唯一有效的解决方案。我需要将位图帧输入到转换的位图中。无法控制创建BitmapFrame的线程,因为它是由库提供的(并且BitmapFrame的Dispatcher属性为null)。甚至查询CanFreeze属性也会导致异常。我有两个选择:对我和其他人的源代码进行彻底的修改,或者使用WriteableBitmap。猜猜我选了哪一个。。。
imgThumb.Dispatcher.Invoke(new Action<BitmapSource>(
delegate(BitmapSource src)
{
imgThumb.Source = src;
}
), bmpSource);