Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET Image.Save方法在Windows 64位上生成不可复制的结果_.net_Image_System.drawing - Fatal编程技术网

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

.NET Image.Save方法在Windows 64位上生成不可复制的结果,.net,image,system.drawing,.net,Image,System.drawing,我正在使用.NETFramework(尝试了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);

我正在使用.NETFramework(尝试了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);                
}
Image sourceToConvert=Bitmap.FromFile(“c:\\tmp\\F1.tif”);
sourceToConvert.Save(“c:\\tmp\\F1\u gen.png”,ImageFormat.png);
对于(int i=0;i<100;i++)
{
sourceToConvert=Bitmap.FromFile(“c:\\tmp\\F1.tif”);
sourceToConvert.Save(“c:\\tmp\\F1\u regen.png”,ImageFormat.png);
如果(!CompareFileBytes(“c:\\tmp\\F1\u gen.png”,“c:\\tmp\\F1\u regen.png”))
MessageBox.Show(“Diff”+i);
}
这将在Windows 64上的迭代8、32、33、73、114、155、196中显示“Diff”,而在32位计算机上不会显示任何错误。 (我使用x86目标;使用x64目标,情况更糟:在迭代12、13、14、15……时出现差异)

有没有办法从Save()获得可复制的结果


可以在此

上找到一个示例图像,我无法解释为什么会发生这种情况,但似乎终结器线程上的
图像
对象的非确定性终结正在影响主线程上图像的编码。(
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
}
使用(Image sourceToConvert=Bitmap.FromFile(“c:\\tmp\\F1.tif”))
sourceToConvert.Save(“c:\\tmp\\F1\u gen.png”,ImageFormat.png);
对于(int i=0;i<100;i++)
{
使用(Image sourceToConvert=Bitmap.FromFile(“c:\\tmp\\F1.tif”))
sourceToConvert.Save(“c:\\tmp\\F1\u regen.png”,ImageFormat.png);
//文件是一样的
}

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

压缩文件时有各种设置,可能在运行时对某些因素进行了优化。例如,字典大小可能会影响压缩输出的大小,但仍会产生相同的解压缩数据。因此,您的图像仍然是相同的,但可能已优化略有不同。可能64位的构建在引擎盖下提供了一些不同的设置。您可以查看保存重载的编码器设置,但我没有立即看到任何会使压缩输出具有确定性的内容。谢谢您的评论。一、 同样,假设图像在内存中应该相同(只有.png文件不同)。但我甚至编写了一个函数,将图像读回为BMP,转换为字节数组,它们是不同的(尽管图像在视觉上没有区别)。我还发现,问题只发生在相对较大的图像上(在我的例子中约为2600x2600像素)。我还尝试了第三方库,如FreeImage-同样的问题:32位上的确定性,而不是64位上的确定性。你能发布一个指向F1.tif图像的链接吗?谢谢你查看-我在这里放了一个:@werner这有答案吗?我想是的。如果是这样,请将答案标记为正确或自行填写。如果没有,请用新的细节编辑你的问题,使之生动起来。谢谢!这有点令人毛骨悚然,稍后完成图像应该会修改它,但是您的解决方案对于我想要做的事情非常有效。杰出的