問題: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
(正しく実行した場合)、実行が再び非常に遅くなります。
私は愚かな間違いを犯していますか?
EDIT:(@ 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)
{
..
}
}
};