title: Why Image.Save() in C# does not always give the same serialized result and how to serialize an image in a deterministic way?
body: <p>I serialize images using the following code:</p>
  <pre><code>public static string SerializeImage(Image image)
  {
      using (MemoryStream memoryStream = new MemoryStream())
      {
          image.Save(memoryStream, image.RawFormat);
  
          return Convert.ToBase64String(memoryStream.ToArray());
      }
  }
  </code></pre>
  <p>and deserialize the images by doing the following</p>
  <pre><code>public static Image DeserializeImage(string serializedImage)
  {
      byte[] imageAsBytes = Convert.FromBase64String(serializedImage);
  
      using (MemoryStream memoryStream = new MemoryStream(imageAsBytes, 0, imageAsBytes.Length))
      {
          memoryStream.Write(imageAsBytes, 0, imageAsBytes.Length);
  
          return Image.FromStream(memoryStream, true);
      }
  }
  </code></pre>
  <p>If I have an image and does</p>
  <pre><code>string serializedImage1 = SerializeImage(image);
  Image deserializedImage = DeserializeImage(serializedImage1);
  string serializedImage2 = SerializeImage(deserializedImage );
  </code></pre>
  <p>Then</p>
  <pre><code>serializedImage1 == serializedImage2;
  </code></pre>
  <p>as expected. <em>But</em> it is not always the case.</p>
  <p>If I serialize an image on Process 1, and then redeserialize and reserialize it on Process 2, then the result of the reserialization on Process 2 is not the same as on the Process 1. Everything works, but a few bytes in the beginning of the serialization are different.</p>
  <p>Worst, if I do the same thing on 2 different dll (or thread, I'm not sure), it seems the serialization result is not the same too. Again, the serialization/deserialization works, but a few bytes are different.</p>
  <p>The image the first time is loaded with the following function :</p>
  <pre><code>public static Image GetImageFromFilePath(string filePath)
  {
      var uri = new Uri(filePath);
      var bitmapImage = new BitmapImage(uri);
      bitmapImage.Freeze();
  
      using (var memoryStream = new MemoryStream())
      {
          var pngBitmapEncoder = new PngBitmapEncoder();
          pngBitmapEncoder.Frames.Add(BitmapFrame.Create(bitmapImage));
          pngBitmapEncoder.Save(memoryStream);
          Image image = Image.FromStream(memoryStream);
  
          return image;
      }
  }
  </code></pre>
  <p>Note however that it happens even if the image is loaded twice with the DeserializeImage() function.</p>
  <p>The tests I have done are with ImageFormat.Jpeg and ImageFormat.Png.</p>
  <p>First question, why it does this ? I would have expected the result to be always the same, but I suppose some salt is used when doing the Image.Save().</p>
  <p>Second question : I want to have a deterministic way to serialize an image, keeping the image format intact. The goal is to save the image in a DB and also to compare serialized images to know if it already exists in the system where this function is used.</p>