'C#, Byte array to System.Drawing.Image error

I am trying to convert some video playback code from Unity to C# WPF, and I have hit a wall with the conversion.

I have my video frame as a

private byte[] _textureBuffer;

and I am using this code:

MemoryStream ms = new MemoryStream(_textureBuffer, 0, _textureBuffer.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image x = System.Drawing.Image.FromStream(ms);

Which results in a 'Parameter is invalid' crash on the last line.

The data is loaded into the buffer correctly and the buffer is filled:

_textureBuffer.Length = 4147200

The image is 3840 x 2160 resolution.

The original fully functional Unity code is:

private void UpdateTexture(int frameAt)
        {
            var block = _lz4Blocks[frameAt];
            _filestream.Seek((long)block.address, SeekOrigin.Begin);
            _filestream.Read(_lz4Buffer, 0, (int)block.size);
            Marshal.Copy(_lz4Buffer, 0, _lz4BufferNative, (int)block.size);
            Lz4Native.lz4_decompress_safe_native(_lz4BufferNative, _textureBufferNative, (int)block.size, _frameBytes);
            Marshal.Copy(_textureBufferNative, _textureBuffer, 0, _frameBytes);
            _texture.LoadRawTextureData(_textureBuffer);
            _texture.Apply();
        }

And my (crashing) WPF version is:

public System.Drawing.Image UpdateTexture(int frameAt)
    {
        var block = _lz4Blocks[frameAt];
        _filestream.Seek((long)block.address, SeekOrigin.Begin);
        _filestream.Read(_lz4Buffer, 0, (int)block.size);
        Marshal.Copy(_lz4Buffer, 0, _lz4BufferNative, (int)block.size);
        Lz4Native.lz4_decompress_safe_native(_lz4BufferNative, _textureBufferNative, (int)block.size, _frameBytes);
        Marshal.Copy(_textureBufferNative, _textureBuffer, 0, _frameBytes);

        MemoryStream ms = new MemoryStream(_textureBuffer, 0, _textureBuffer.Length);
        ms.Seek(0, SeekOrigin.Begin);
        System.Drawing.Image x = System.Drawing.Image.FromStream(ms);

        return x;

        //  _texture.LoadRawTextureData(_textureBuffer);
        //  _texture.Apply();
    }

This question says that the image data is not in the correct format, but has no answer for how to fix it.

Where am i going wrong?

EDIT: Using lockbits as suggested, yields me an image:

Bitmap x = new Bitmap(_width, _height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                BitmapData bmpData = x.LockBits(new System.Drawing.Rectangle(0, 0, x.Width, x.Height), ImageLockMode.WriteOnly, x.PixelFormat);
                Marshal.Copy(_textureBuffer, 0, bmpData.Scan0, _textureBuffer.Length);
                x.UnlockBits(bmpData);

However it is scrambled.

enter image description here

When i expect:

enter image description here

and using Format8bppIndexed as suggested:

enter image description here



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source