保存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();
}
}
修正后的代码工作正常。