当我尝试使用BinaryFormatter序列化一些图像时,我会得到一个ExternalException - GDI +中发生了一般错误。“在我抓了一会儿之后,我决定创建一个简单的测试项目缩小问题范围:
static void Main(string[] args)
{
string file = @"C:\temp\delme.jpg";
//Image i = new Bitmap(file);
//using(FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
byte[] data = File.ReadAllBytes(file);
using(MemoryStream originalms = new MemoryStream(data))
{
using (Image i = Image.FromStream(originalms))
{
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
// Throws ExternalException on Windows 7, not Windows XP
bf.Serialize(ms, i);
}
}
}
}
对于特定的图像,我尝试了各种加载图像的方法,即使以管理员身份运行程序,也无法在Windows 7下运行。
我已将完全相同的可执行文件和图像复制到我的Windows XP VMWare实例中,我没有遇到任何问题。
任何人都知道为什么某些图像在Windows 7下不起作用,但在XP下工作?
以下是其中一张图片: http://www.2shared.com/file/7wAXL88i/SO_testimage.html
delme.jpg md5:3d7e832db108de35400edc28142a8281
答案 0 :(得分:4)
正如OP指出的那样,所提供的代码抛出一个异常,它似乎只发生在他提供的图像上,但与我机器上的其他图像一起正常工作。
选项1
static void Main(string[] args)
{
string file = @"C:\Users\Public\Pictures\delme.jpg";
byte[] data = File.ReadAllBytes(file);
using (MemoryStream originalms = new MemoryStream(data))
{
using (Image i = Image.FromStream(originalms))
{
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
// Throws ExternalException on Windows 7, not Windows XP
//bf.Serialize(ms, i);
i.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // Works
i.Save(ms, System.Drawing.Imaging.ImageFormat.Png); // Works
i.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); // Fails
}
}
}
}
可能是有问题的图像是使用一个工具创建的,该工具添加了一些干扰JPEG序列化的附加信息。
P.S。可以使用 BMP 或 PNG 格式将图像 保存到内存流中。如果更改格式是一个选项,那么您可以尝试使用 ImageFormat 中定义的这些或任何其他格式。
选项2 如果您的目标只是将图像文件的内容放入内存流中,那么只需执行以下操作即可
static void Main(string[] args)
{
string file = @"C:\Users\Public\Pictures\delme.jpg";
using (FileStream fileStream = File.OpenRead(file))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
}
}
答案 1 :(得分:2)
虽然Bitmap
类标记为[Serializable]
,但它实际上不支持序列化。您可以做的最好的事情是序列化包含原始图像数据的byte[]
,然后使用MemoryStream
和Image.FromStream()
方法重新创建它。
我无法解释您遇到的不一致行为;对我来说,它无条件失败(虽然我在尝试在不同应用程序域之间编组图像时首先发现了这一点,而不是手动将它们序列化)。
答案 2 :(得分:1)
我不确定,但我倾向于XP和Windows 7的不同安全模型。图片继承自System.MarshalByRefObject。执行序列化时,应用程序域之间可能正在进行代理。在Windows 7中可能禁止此代理。
http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject%28v=vs.71%29.aspx