'Why Image.Save() in C# does not always give the same serialized result and how to serialize an image in a deterministic way?
I serialize images using the following code:
public static string SerializeImage(Image image)
{
using (MemoryStream memoryStream = new MemoryStream())
{
image.Save(memoryStream, image.RawFormat);
return Convert.ToBase64String(memoryStream.ToArray());
}
}
and deserialize the images by doing the following
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);
}
}
If I have an image and does
string serializedImage1 = SerializeImage(image);
Image deserializedImage = DeserializeImage(serializedImage1);
string serializedImage2 = SerializeImage(deserializedImage );
Then
serializedImage1 == serializedImage2;
as expected. But it is not always the case.
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.
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.
The image the first time is loaded with the following function :
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;
}
}
Note however that it happens even if the image is loaded twice with the DeserializeImage() function.
The tests I have done are with ImageFormat.Jpeg and ImageFormat.Png.
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().
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
