'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.
When i expect:
and using Format8bppIndexed as suggested:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|