用GDI+保存Image到流时的一个有趣现象

这两天做一个自己玩的项目,发现了一个奇怪的现象,大致情况是这样的。

我需要把一个Image对象写入流中,使用的是Image.Save(Stream, ImageFormat)这个重载,而在之前我已经在这个流中写入了其它数据。

我的开发环境是Win7+VS2010,使用的框架是.net 3.5 Client Profile,在开发时一切正常。可当我把编译好的程序放到XP的系统中运行时就发现了问题,图片数据在写入流的时候,并没有写到流的当前位置,而是写到了流的起始位置上,把我原来写在里面的数据给破坏掉了。

后来我查了MSDN关于这个Save方法的说明,里面有这么一句话:

The image must be saved to the stream at an offset of zero. If any additional data has been written to the stream before saving the image, the image data in the stream will be corrupted. 

大致意思是图片必须保存流中位置为0的地方,并且之前已经写入流中的数据会被破坏。

原来如此,可为什么在Win7里是好的呢。于是我做了一个简单的试验,结果发现在Win7中数据写入后,流中原来的数据并不会被覆盖,而在XP中,也并不是所有的图片格式会发生这样的情况。我测试了PNG和JPG两种格式,发现PNG会造成数据的损坏,而JPG不会。测试代码如下:

 测试代码

    public void Test()
    {
            FileInfo file 
= new FileInfo(Path.GetTempFileName());
            
try
            {
                
using (Bitmap bm = new Bitmap(3232))
                {
                    
using (var stream = file.OpenWrite())
                    {
                        stream.WriteByte(
9);
                        stream.WriteByte(
7);
                        stream.WriteByte(
2);
                        stream.WriteByte(
6);

                        
// 在这里更改图片的格式
                        bm.Save(stream, ImageFormat.Jpeg);
                    }
                }

                
using (var stream = file.OpenRead())
                {
                    
byte[] buf = new byte[4];
                    stream.Read(buf, 
04);

                    
// 如果显示的信息是09-07-02-06说明数据没有被破坏
                    MessageBox.Show(BitConverter.ToString(buf));

                }

            }
            
catch (Exception x)
            {
                MessageBox.Show(x.ToString());
            }
            
finally
            {
                file.Delete();
            }
    }
原文地址:https://www.cnblogs.com/effun/p/1912535.html