I am using the Kinect SDK to capture an RGB stream. I am capturing the data at:
ColorImageFormat.RawBayerResolution640x480Fps30
More info on available formats
here. I want to store this stream on disk, so I am using a binary writer to write the raw frame bytes of the color image. This works well but the size on disk is very large. I intend to compress each image as it arrives (30 images per second) to JPEG format. I achieve this using the following code:
public byte[] GetPngImage(byte[] imageData, System.Windows.Media.PixelFormat format, int width = 640, int height = 480)
{
using (MemoryStream memoryStream = new MemoryStream())
{
BitmapSource src = ToBitmapSource(imageData, format, (int)width, (int)height);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Interlace = PngInterlaceOption.On;
encoder.Frames.Add(BitmapFrame.Create(src));
encoder.Save(memoryStream);
return memoryStream.ToArray();
}
}
public BitmapSource ToBitmapSource(byte[] data, PixelFormat format, int width, int height)
{
return BitmapSource.Create(width, height, 96, 96, format, null, data, width * format.BitsPerPixel / 8);
}
I can decompress and display when reading back in again using the following code:
public byte[] GetBmpImage(byte[] JpegImageData)
{
using (MemoryStream memoryStream = new MemoryStream(JpegImageData))
{
PngBitmapDecoder decoder = new PngBitmapDecoder(memoryStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
using (MemoryStream output = new MemoryStream())
{
BmpBitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(decoder.Frames[0]);
enc.Save(output);
return output.ToArray();
}
}
}
Then this code to render:
PixelFormat format = PixelFormats.Rgb24;
if (ImageSource == null)
ImageSource = new WriteableBitmap(frame.Width, frame.Height, 96, 96, format, null);
var stride = frame.Width * format.BitsPerPixel / 8;
byte[] bmpBytes = frame.GetBmpImage(pixelData);
bmpBytes = ReverseFrameInPlace2(stride, bmpBytes);
imgPic.Source = System.Windows.Media.Imaging.BitmapSource.Create((int)frame.Width, (int)frame.Height, 96, 96, format, null, bmpBytes, stride);
The color of the image seems wrong when I render it. Lots of blues and reds. I haven't defined a palette anywhere as Im not sure how to apply a palette to the image or what the different stride calculations should be for each of the formats.
Any advice greatly appreciated!