0

I would like to serialize System.Windows.Media.PixelFormat object, and then recreate it by deserialization. What I'm doing:

BitmapSource bitmapSource = backgroundImage.ImageSource as BitmapSource;
PixelFormat pixelFormat = bitmapSource.Format;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("test", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, pixelFormat);
stream.Close();

and then

PixelFormat pixelFormat;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("test", FileMode.Open, FileAccess.Read, FileShare.Read);
pixelFormat = (PixelFormat)formatter.Deserialize(stream);
stream.Close();

The serialization doesn't give any error. When I try to deserialize this object it also doesn't give any error, but the returned object isn't good, for example in the BitsPerPixel field it has BitsPerPixel = 'pixelFormat.BitsPerPixel' threw an exception of type 'System.NotSupportedException'

@edit I have a work around of this problem. We must use PixelFormatConverter to convert PixelFormat object to string and then serialize the string. When deserializing we get the string and using PixelFormatConverter convert it back to PixelFormat.

  • Are you deserializing on the same or a different computer? Supported values of some of the properties do vary with hardware (and drivers). – Ben Voigt Dec 06 '15 at 23:11
  • I serialize and deserialize on the same computer. – Russian Gepetto Dec 06 '15 at 23:12
  • 1
    You might want to check the [source code of PixelFormat](http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Media/PixelFormat.cs,514cf14a5172deb3,references). It is basically just a wrapper for an enum-like construct. Maybe you could serialize `pixelFormat.ToString()` and then use `PixelFormatConverter` to convert that string back to `PixelFormat`? – vesan Dec 07 '15 at 00:57

1 Answers1

0

While System.Windows.Media.PixelFormat is marked as [Serializable], every single one of its fields are marked [NonSerialized]. Thus, when you serialize the type using BinaryFormatter, no information is actually written to the output stream.

This means that when you try to deserialize the object, the fields are not correctly restored to their original value (nor initialized at all, other than their default values, for that matter), leaving the deserialized value of PixelFormat invalid. So of course, if you try to e.g. retrieve its BitsPerPixel, and it tries to determine the bits per pixel for the invalid format, you get an exception.

As you've found, serializing the value as a string and then converting back on deserialization works. For example:

BitmapSource bitmapSource = backgroundImage.ImageSource as BitmapSource;
string pixelFormat = bitmapSource.Format.ToString();
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("test", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, pixelFormat);
stream.Close();

And then:

PixelFormat pixelFormat;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("test", FileMode.Open, FileAccess.Read, FileShare.Read);
pixelFormat = (PixelFormat)new PixelFormatConverter()
    .ConvertFromString((string)formatter.Deserialize(stream));
stream.Close();

You could, of course, do that explicitly yourself, enumerating the properties in PixelFormats and looking the value up (or building a Dictionary<string, PixelFormat> based on the members of that class). But the PixelFormatConverter is convenient and does just what you want.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136