保存Bitmap到内存流中引发“GDI+中发生一般性错误”

保存Bitmap到流中引发“GDI+中发生一般性错误”

 

 -----------------------------------------------------------------------------------------

 

在.NET中进行图像很容易处理引发“GDI+中发生一般性错误”,最近我就碰到了一次。其场景如下:

 

SQL Server数据库表中有一CoverImage字段,其类型为varbinary,用于保存图像的二进制数据。

 

我需要在一个Windows Form应用程序中使用PictureBox(名为picCoverImage)从本地硬盘加载图片文件显示,然后,再将图像本身塞入到数据库中。

 

我采用的方法是将PictureBox的Image属性引用的图像对象先转换为字节数组,再使用LINQ to SQL更新回数据库:

 

//……

           if (picCoverImage.Image != null)
            {

               using (MemoryStream mem = new MemoryStream())
                {
                    picCoverImage.Image.Save(mem, picCoverImage.Image.RawFormat);

                    //book是LINQ to SQL生成的数据实体对象
                    book.CoverImage = new Binary(mem.ToArray());
                   
                }

}

//……

 

然而,很奇怪的是,上述代码在往数据库中新加图像时是成功的,而一旦要修改时picCoverImage.Image.Save(...)一句总引发“GDI+中发生一般性错误”。

 

仔细对比“新建”与“修改”的不同流程:

 

“新建”时,我是使用OpenFileDialog选择文件,然后设置PictureBox的ImageLocation属性装载并显示图片,上述代码运行正常。

 

“修改”时,我从数据库中取出图像数据,使用以下方法在PictureBox中显示图片:

 

//显示图像
            if (book.CoverImage != null)
            {
                using (MemoryStream mem = new MemoryStream(book.CoverImage.ToArray()))
                {
                    picCoverImage.Image = new Bitmap(mem);
                }
            }

 

现在,再次尝试将PictureBox中的Image写入到内存流中,picCoverImage.Image.Save(...)一句就引发“GDI+中发生一般性错误”。

 

百思不得其解。估计是PictureBox内部对Image引用的图像进行了特殊处理,也没时间去用Reflector等工具去深挖细掘,最后是用这个笨方法解决的:

 

克隆一个新的Bitmap对象。

 

修正后的代码如下:

 

//更新图像
            if (picCoverImage.Image != null)
            {

                using (MemoryStream mem = new MemoryStream())
                {
                    //克隆Bitmap对象
                    Bitmap bmp = new Bitmap(picCoverImage.Image);
                    bmp.Save(mem, picCoverImage.Image.RawFormat);
                    book.CoverImage = new Binary(mem.ToArray());
                     bmp.Dispose();
                }
            }

 

修正后的代码工作正常。

 

 

 

 

你可能感兴趣的:(编程技术)