问题:如何相对于主线程异步保存/压缩位图图像(其中几个堆叠在tiff
文件中)?
我的设置:(同步和慢速工作解决方案:执行压缩时,线程会停留几秒钟。我负担不起。)
...in the body of a window class
private void afunction(){
//called with a given frequency and updating this.colorBitmap
...
this.colorBitmap = something;
savePictureStackTiff();
}
private int stack_pict_count = 0;
private int PICT_PER_FILE = 45;
private TiffBitmapEncoder encoder;
private string savePictureStackTiff()
{
initializeTiffEncoder();
//make a local copy of the image I want to put in the tiff binder
WriteableBitmap localCopy = new WriteableBitmap(this.colorBitmap);
encoder.Frames.Add(BitmapFrame.Create(localCopy));
stack_pict_count++;
if (stack_pict_count % PICT_PER_FILE == 0)
//Once I have enough files stacked I ask for compression
{
stack_pict_count = 0;
pict_metadata = "";
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs); //<<<== LINE WHICH I'D LIKE TO BE RUN ASYNC
}
}
catch (IOException)
{}
}
}
private void initializeTiffEncoder()
{
if (stack_pict_count == 0)
{
encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Zip;
}
}
我一直在尝试:我希望压缩(调用encoder.save(fs)
)在主线程之外的另一个线程中执行。
我尝试将encoder.save(fs)
调用BackgroundWorker
来预防性地将编码器复制到本地版本(不确定它是否有效),然后拨打电话。
我收到错误,如'调用线程无法访问此对象,因为另一个线程拥有它'。
如果我使用Dispatcher.Invoke
(如果我正确地做了),执行将变得非常缓慢。
我犯了一些愚蠢的错误吗?
编辑:(根据@meilke和@ user7116的建议正在进行中)
我现在在BackgroundWorker
中移动了压缩器的分配和执行。虽然现在传递colorBitmap
,但拥有另一个线程。我试着freeze
它,但看起来不够;我仍然得到一个'调用线程无法访问此对象,因为另一个线程拥有它'。
tiffCompressorWorker = new BackgroundWorker();
tiffCompressorWorker.DoWork += (s, a) =>
{
initializeTiffEncoder();
WriteableBitmap localCopy = new WriteableBitmap((WriteableBitmap)a.Argument);
localCopy.Freeze();
encoder.Frames.Add(BitmapFrame.Create(localCopy));
stack_pict_count++;
if (stack_pict_count % PICT_PER_FILE == 0)
{
stack_pict_count = 0;
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
saving_encoder.Save(fs);
}
}
catch (IOException)
{
..
}
}
};
答案 0 :(得分:2)
您必须将整个TIFF操作放入后台工作程序。然后将输入图像的副本作为参数传递给RunWorkerAsync
。以下链接指向网络上提供的众多解决方案之一:Copying from BitmapSource to WritableBitmap。将该代码放入辅助方法并使用它复制映像,然后再将其保存到磁盘。
答案 1 :(得分:0)
我不是计算机科学家,但我找到了this post,其中指出:
WriteableBitmap继承DispatcherObject,并且只能在拥有它的调度程序线程中访问。
而且,在我看来,你正在超越DispatcherObject的权限。