MartynW
MartynW

Reputation: 709

Converting byte array to image and back again does not return the same array

I have two c# functions that convert byte[] to images and back. I thought that the two functions would be exactly reversible:

        public static byte[] ImageToByte(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();
                return imageBytes;
            }
        }

        public static Image ByteToImage(byte[] imageBytes)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(imageBytes, 0, imageBytes.Length);
                Image returnImage = Image.FromStream(ms);
                return returnImage;
            }
        }

However, if i look at the original byte array and then converted/reconverted array they are different (different lengths). I am not clear why? I would like to be able to tell if the image has been modified in my app so need to be able to compare the image array before and after.

Thanks

Upvotes: 0

Views: 1016

Answers (1)

There is no reason to expect that both functions are reversible to get identical byte data, unless you choose an image format that does not use compression schemes controlled by variable parameters (like PNG or JPG, for example) and does not feature metadata fields that can change without altering the pixel data (like bytes 6...9 in a BMP format header, for example), or are not maintained by the infrastructure underlying System.Drawing.Image.

Instead of trying to compare the raw byte data (which can be variable depending on the image file format being used), compare the actual pixel data. In other words, load both your "before" image and "after" image into System.Drawing.Image instances, and then compare the pixel data of both images. Make sure both image instances use the same pixel format before you compare the pixel data. (Use the widest pixel format available like 64bppArgb to avoid potential reduction of the color space of the images loaded, which otherwise could spoil your efforts.) Also make sure that you don't use a "lossy" format like JPEG for your "before" and "after" pictures, otherwise the simple act of uncompressing/decoding and re-compressing/encoding of the image might change the actual pixel data.

Upvotes: 1

Related Questions