.NET Image.Save方法在Windows 64位上生成不可重现的结果

wer*_*ner 8 .net system.drawing image

我正在使用.NET框架(尝试3.5和4.0)加载.TIFF文件并将其另存为.PNG.我希望两次后续调用Save()方法(使用相同的TIFF文件)来生成相同的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);                
}
Run Code Online (Sandbox Code Playgroud)

这将在Windows 64上的迭代8,32,33,73 114,155,196处显示"Diff",而在32位计算机上不显示任何错误.(我使用x86目标;使用x64目标,情况更糟:迭代12,13,14,15 ......的差异)

有没有办法从Save()获得可重现的结果?

可以在此FTP站点上找到示例图像

Bra*_*ger 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
}
Run Code Online (Sandbox Code Playgroud)

请注意,我确实发现了另一个奇怪之处:在 Windows 7 SP1 x64 上运行 32 位 (x86) 版本时,前两次调用返回Save不同的结果,然后每个后续调用都会Save产生与第二次调用相同的输出。为了使测试通过,我必须重复前两行(在循环之前)以在执行相等性检查之前强制进行两次保存。