BinaryFormatter.Serialize( Image ) - ExternalException - A generic error occurred in GDI+

后端 未结 3 1168
清酒与你
清酒与你 2021-01-14 10:35

When I try to Serialize some images using the BinaryFormatter, I\'ll get a ExternalException - A generic error occurred in GDI+.\" After scratching my head for awhi

相关标签:
3条回答
  • 2021-01-14 10:43

    As the OP pointed out, the code provided throws an exception that seems to be occurring only with the image he provided but works fine with other images on my machine.

    Option 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
                }    
             }
         }
    }
    

    It could be that the image in question was created with a tool that added some additional information that is interfering with the JPEG serialization.

    P.S. The image can be saved to memory stream using BMP or PNG format. If changing the format is an option, then you can try out either of these or any other format defined in ImageFormat.

    Option 2 If your goal is just to get the contents of the image file into a memory stream, then doing just the following would help

    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);
        }
    }
    
    0 讨论(0)
  • 2021-01-14 11:03

    I don't know for sure but I would lean towards different security models for XP vs Windows 7. Image inherits from System.MarshalByRefObject. There is probably proxying going on between application domains when serialization is performed. This proxying might be forbidden in Windows 7.

    http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject%28v=vs.71%29.aspx

    0 讨论(0)
  • 2021-01-14 11:08

    Although the Bitmap class is marked as [Serializable], it does not actually support serialisation. The best you can do is serialise the byte[] containing the raw image data and then re-create it using a MemoryStream and the Image.FromStream() method.

    I can't explain the inconsistent behaviour you're experiencing; for me, it fails unconditionally (although I first discovered this when trying to marshal images between different app domains, rather than manually serialising them).

    0 讨论(0)
提交回复
热议问题