9

私は.NETフレームワーク(3.5と4.0を試しました)を使用して.TIFFファイルをロードし、.PNGとして保存しています。(同じ TIFF ファイルを使用して) Save() メソッドを 2 回続けて呼び出すと、同じ PNG ファイルが生成されると思います。ただし、生成されるファイルは「場合によっては」異なります。

以下の C# コードは、問題を示しています。

Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif");
sourceToConvert.Save("c:\\tmp\\F1_gen.png", ImageFormat.Png);           

for (int i = 0; i < 100; i++)
{
    sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif");
    sourceToConvert.Save("c:\\tmp\\F1_regen.png", ImageFormat.Png);

    if (!CompareFileBytes("c:\\tmp\\F1_gen.png", "c:\\tmp\\F1_regen.png"))
        MessageBox.Show("Diff" + i);                
}

これにより、Windows 64 では反復 8、32、33、73、114、155、196 で「Diff」が表示されますが、32 ビット マシンではエラーは表示されません。(私は x86 ターゲットを使用します。x64 ターゲットでは、さらに悪化します: 反復 12、13、14、15 での差分...)

Save() から再現可能な結果を​​得る方法はありますか?

サンプル画像は、このFTP サイトにあります。

4

1 に答える 1

2

なぜこれが起こっているのか説明できませんが、ファイナライザー スレッドでのImageオブジェクトの非決定論的なファイナライズが、メイン スレッドでの画像のエンコードに影響を与えているようです。(Imageを実装IDisposableしているので、使い終わったときに決定論的にクリーンアップするためにそれを呼び出す必要がありDisposeます。そうしないと、将来の任意の時点でファイナライズされます。)

サンプル コードを次のように変更すると、すべての呼び出しから同じ結果が得られますSave

using (Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif"))
    sourceToConvert.Save("c:\\tmp\\F1_gen.png", ImageFormat.Png);           

for (int i = 0; i < 100; i++)
{
    using (Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif"))
        sourceToConvert.Save("c:\\tmp\\F1_regen.png", ImageFormat.Png);

    // files are the same
}

さらに奇妙な点が 1 つあります。Windows 7 SP1 x64 で 32 ビット (x86) ビルドを実行すると、最初の2 つの呼び出しでSave異なる結果が返され、その後のすべての呼び出しSaveで 2 番目の呼び出しと同じ出力が生成されました。テストに合格するには、最初の 2 行 (ループの前) を繰り返して、等価チェックを実行する前に 2 回の保存を強制する必要がありました。

于 2012-06-09T20:32:42.810 に答える