0

i have a problem with convert byte[] to .jpg file. When I try to convert byte, I got a exception in this method:

using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length))
{
   ms.Write(bytes, 0, bytes.Length);
   Image image = Image.FromStream(ms, true, false);
}

Exception:

The parameter is invalid in System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData)

Any suggestion?

R Pelzer
  • 1,188
  • 14
  • 34
Mear Elin
  • 79
  • 1
  • 7

1 Answers1

2

Solution*: Remove the line: ms.Write(bytes, 0, bytes.Length);

* If this doesn't work, the bytes array doesn't contain valid image data.


Reason:

This line initializes a MemoryStream with the bytes in a byte array. It will start the stream at position 0 (the beginning):

using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length))

and in your case it can be simplified to:

using (MemoryStream ms = new MemoryStream(bytes))

This line then writes the same bytes into the stream. It will leave your stream at position bytes.Length (the end):

ms.Write(bytes, 0, bytes.Length);

This line will try to read an image from the stream starting at the current position (the end). Since 0 bytes don't make an image, it fails giving you the exception:

Image image = Image.FromStream(ms, true, false);

As noted by Jimi, it might be better wrapping this up into a method:

public static Image ImageFromByteArray(byte[] bytes)
{
    using (MemoryStream ms = new MemoryStream(bytes))
    using (Image image = Image.FromStream(ms, true, true))
    {
        return (Image)image.Clone();
    }
}

The reason for using Clone() is that it can cause trouble saving the image if the original stream has been disposed of.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • 1
    Just a suggestion, to avoid headaches. It would be better to convert this to a method and return the Image this way: `ms.Position = 0; `using (Image image = Image.FromStream(ms, true)) { return (Image)image.Clone(); }`. The Image should be detached from the Stream (which is immediately disposed of when exiting the `using` block). Or declare the `Image` object outside the `using` block and assign the cloned Image to it. – Jimi Dec 06 '18 at 07:37
  • Ok, thanks but still have a problem. I convert to Byte this string: "0x78DAED7A6758934BB776A8B211...." and I have the same exception "Parameter is invalid"... Do you have any solution for this situation? – Mear Elin Dec 06 '18 at 08:13
  • @Mear your image data is likely valid. If you can provide it via a site like pastebin I can take a look if you like. – ProgrammingLlama Dec 06 '18 at 08:14
  • That doesn't appear to be a valid image format. If I convert it to a binary file and open it with a hex editor, I can't see any kind of image header. Where did you get this data? – ProgrammingLlama Dec 06 '18 at 08:23
  • In details this file in topic I have "OLYMPUS DIGITAL CAMERA" and property compressed bits/pixel set to 2. Maybe this is a problem? – Mear Elin Dec 06 '18 at 09:14
  • Do you have the original file? or just the byte data? – ProgrammingLlama Dec 06 '18 at 09:30
  • No, I have only byte array. I received information, that this by is compressed by Zlib but I don't know how to decompress this array and save as .jpg file...Somebody know how to do this? – Mear Elin Dec 07 '18 at 18:06
  • 1
    "compressed by Zlib" - this is a critically important piece of information. – ProgrammingLlama Dec 08 '18 at 00:35
  • You'll need to decompress the byte array using something similar to what is mentioned [here](https://stackoverflow.com/questions/41238898/c-decompress-a-stream-using-zlib). – ProgrammingLlama Dec 08 '18 at 02:36