/// <summary> /// Extract the player image /// </summary> /// <param name="colorInfo">The color information</param> private void WriteColorPixels(ColorImageFrameInfo colorInfo) { if (_colorBitmap == null) { _colorBitmap = new WriteableBitmap(colorInfo.Width, colorInfo.Height, 96.0, 96.0, PixelFormats.Bgr32, null); } // Write the color pixel data into our bitmap _colorBitmap.WritePixels( new Int32Rect(0, 0, _colorBitmap.PixelWidth, _colorBitmap.PixelHeight), colorInfo.FrameData, _colorBitmap.PixelWidth * sizeof(int), 0); }
/// <summary> /// Do the image composition /// </summary> /// <param name="tuple">The depth and color information</param> /// <param name="image">The background image</param> private void Merge(Tuple <DepthImageFrameInfo, ColorImageFrameInfo> tuple, BitmapSource image) { //No background if (image == null) { return; } DepthImageFrameInfo depthInfo = tuple.Item1; ColorImageFrameInfo colorInfo = tuple.Item2; //Initiate buffer if (_greenScreenPixelData.Length != depthInfo.DepthStreamFramePixelDataLength) { _greenScreenPixelData = new int[depthInfo.DepthStreamFramePixelDataLength]; } Array.Clear(_greenScreenPixelData, 0, _greenScreenPixelData.Length); //Initiate buffer if (_colorCoordinates.Length != depthInfo.DepthStreamFramePixelDataLength) { _colorCoordinates = new ColorImagePoint[depthInfo.DepthStreamFramePixelDataLength]; } Array.Clear(_colorCoordinates, 0, _colorCoordinates.Length); _kinectManager.MapDepthFrameToColorFrame( depthInfo.Format, depthInfo.FrameData, colorInfo.Format, _colorCoordinates); // loop over each row and column of the depth for (int y = 0; y < depthInfo.Height; ++y) { WritePlayersMask(depthInfo, y); } WriteColorPixels(colorInfo); //Use the bigger image as the size for the resulting picture int width = Math.Max(colorInfo.Width, image.PixelWidth); int height = Math.Max(colorInfo.Height, image.PixelHeight); // create a render target that we'll render our images to var renderBitmap = new RenderTargetBitmap(width, height, 96.0, 96.0, PixelFormats.Pbgra32); var imageBrushSource = new ImageBrush { ImageSource = image, Stretch = Stretch.Fill, TileMode = TileMode.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top, Opacity = 1, }; var imageBrushMask = new ImageBrush { ImageSource = _playerOpacityMaskImage, Stretch = Stretch.UniformToFill, TileMode = TileMode.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top, Opacity = 1, }; var imageBrushPlayer = new ImageBrush { ImageSource = _colorBitmap, Stretch = Stretch.UniformToFill, TileMode = TileMode.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top, Opacity = 1, }; var drawingVisual = new DrawingVisual(); //Compose images using (DrawingContext dc = drawingVisual.RenderOpen()) { dc.DrawRectangle(imageBrushSource, null /* no pen */, new Rect(0, 0, width, height)); dc.PushOpacityMask(imageBrushMask); dc.DrawRectangle(imageBrushPlayer, null /* no pen */, new Rect(0, 0, width, height)); } var result = new RenderTargetBitmap(width, height, renderBitmap.DpiX, renderBitmap.DpiY, renderBitmap.Format); result.Render(drawingVisual); //Make it thread context free result.Freeze(); //broadcast the result _resultBlock.SendAsync(result); }