0

I have a JPEG stored as a byte array, and I would like to convert it to a System.Drawing.Image, as shown below:

using(var ms = new MemoryStream(myArray))
{
    img = System.Drawing.Image.FromStream(ms);
    Console.WriteLine(ImageToByteArray(img).Length);
}

However, the problem that I'm running into is that I'm losing and my image is degrading. My initial array is 2673030 bytes long, as is the MemoryStream, but when I look at the length of the img, it is only 2672013 bytes long. What's even stranger is that when I run this snippet on our docker container, the image is shrunk down all the way to 1700324 bytes. These sizes are from the print statement shown, so it doesn't have to do with the file format.

I've tried reading from the stream as a BitMap, and I've also tried writing the byte array to a file and creating the image/bitmap directly from the file, all with the exact same resize results.

The heart of the problem is that my images are losing quality when I save them to the server. As far as I can tell, the only difference is that FromStream() returns differently sized images, so does anyone know of a) a way to create my image without losing data, and b) why it is getting resized differently on different machines? A) is a much higher priority answer.

private byte[] ImageToByteArray(System.Drawing.Image imageIn)
    {
        using (var ms = new MemoryStream())
        {
            imageIn.Save(ms, imageIn.RawFormat);
            return ms.ToArray();
        }
    }
  • 1
    The `Image` object have many many format. if you save the image at 8 bpp vs 12bpp you end end up with larger size in the second case even tough the image remain visually the same. The real question here to you would be : Why on earth do you need to have a specific byte size for an image ? And why you seems to think file size difference is bad. Do you save on Ext, NTFS, FAT16, FAT32 all these different disk format change the file size. – Franck Sep 30 '20 at 20:20
  • 1
    This is unanswerable without knowing more about `myArray`. What kind of image byte stream are you trying to read in? PNG? JPEG? BMP? Raw luma values? Is it compressed? Where's your code that saves `img`? Is it possible that you're saving a re-compressed version of it which may reduce its size? How are you measuring the "length" of `img`? Have you included the image header in your measurements? – Jeff Sep 30 '20 at 20:26
  • You say the original format is JPEG, so `RawFormat` will be JPEG, and you will save it again as JPEG. JPEG is lossy. Every time you reencode an image as JPEG, **it loses information**. If you want to preserve the original quality, why not just save the original bytes? Anyway, see duplicates for advice on dealing with JPEG's "lossy-ness" and other image file formats. – Peter Duniho Sep 30 '20 at 20:58
  • I think it depends on the encoders installed on the machine. See [Using Image Encoders and Decoders in Managed GDI+](https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/using-image-encoders-and-decoders-in-managed-gdi?view=netframeworkdesktop-4.8), https://stackoverflow.com/a/14834923/5045688 – Alexander Petrov Sep 30 '20 at 21:01
  • What is the point of taking the bytes, making them into an Image, and then making bytes out of that again? Can't you just simply preserve those original bytes? The operation here that 'loses' bytes is not the conversion to image object, it's the re-saving. – Nyerguds Nov 02 '20 at 07:59

0 Answers0