private void ColorSensor_OnNewFrame(VideoStream vStream) { if (!vStream.IsValid || !vStream.IsFrameAvailable()) return; VideoFrameRef frame = vStream.ReadFrame(); if (!frame.IsValid) return; lock (colorMutex) { colorFrame = frame; } }
private void CurrentSensorOnNewFrame(VideoStream videoStream) { if (videoStream.IsValid && videoStream.IsFrameAvailable()) { using (VideoFrameRef frame = videoStream.ReadFrame()) { if (frame.IsValid) { VideoFrameRef.CopyBitmapOptions options = VideoFrameRef.CopyBitmapOptions.Force24BitRgb | VideoFrameRef.CopyBitmapOptions.DepthFillShadow; if (this.cb_invert.Checked) { options |= VideoFrameRef.CopyBitmapOptions.DepthInvert; } if (this.cb_equal.Checked) { options |= VideoFrameRef.CopyBitmapOptions.DepthHistogramEqualize; } if (this.cb_fill.Checked) { options |= videoStream.Mirroring ? VideoFrameRef.CopyBitmapOptions.DepthFillRigthBlack : VideoFrameRef.CopyBitmapOptions.DepthFillLeftBlack; } lock (this.bitmap) { /////////////////////// Instead of creating a bitmap object for each frame, you can simply /////////////////////// update one you have. Please note that you must be very careful /////////////////////// with multi-thread situations. try { frame.UpdateBitmap(this.bitmap, options); } catch (Exception) { // Happens when our Bitmap object is not compatible with returned Frame this.bitmap = frame.ToBitmap(options); } /////////////////////// END NOTE /////////////////////// You can always use .toBitmap() if you dont want to /////////////////////// clone image later and be safe when using it in multi-thread situations /////////////////////// This is little slower, but easier to handle // bitmap = frame.toBitmap(options); /////////////////////// END NOTE if (this.cb_mirrorSoft.Checked) { this.bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX); } } ///////////////////// You can simply pass the newly created/updated image to a ///////////////////// PictureBox right here instead of drawing it with Graphic object // this.BeginInvoke(new MethodInvoker(delegate() // { // if (!pb_image.Visible) // pb_image.Visible = true; // if (bitmap == null) // return; // lock (bitmap) // this.BeginInvoke happens on UI Thread so it is better to always keep this lock in place // { // if (pb_image.Image != null) // pb_image.Image.Dispose(); // /////////////////////// If you want to use one bitmap object for all frames, the // /////////////////////// best way to prevent and multi-thread access problems // /////////////////////// is to clone the bitmap each time you want to send it to PictureBox // pb_image.Image = new Bitmap(bitmap, bitmap.Size); // /////////////////////// END NOTE // /////////////////////// If you only use toBitmap() method. you can simply skip the // /////////////////////// cloning process. It is perfectly thread-safe. // //pb_image.Image = bitmap; // /////////////////////// END NOTE // pb_image.Refresh(); // } // })); ///////////////////// END NOTE if (!this.pb_image.Visible) { this.Invalidate(); } } } } }
private void CurrentSensorOnNewFrame(VideoStream vStream) { if (vStream.IsValid && vStream.IsFrameAvailable() && !this.isIdle) { using (VideoFrameRef frame = vStream.ReadFrame()) { if (frame.IsValid) { lock (this.bitmap) { try { frame.UpdateBitmap(this.bitmap, this.renderOptions); } catch (Exception) { this.bitmap = frame.ToBitmap(this.renderOptions); } Rectangle position = new Rectangle(new Point(0, 0), this.bitmap.Size); if (this.currentCropping == Rectangle.Empty) { this.currentCropping = position; } if (Settings.Default.SmartCam) { if (this.activeUserId > 0) { position.X = (int)(this.activePosition.X * this.bitmap.Size.Width); position.Width = (int)(this.activePosition.Width * this.bitmap.Size.Width); position.Y = (int)(this.activePosition.Y * this.bitmap.Size.Height); position.Height = (int)(this.activePosition.Height * this.bitmap.Size.Height); position.Width = (int) (((Decimal)this.bitmap.Size.Width / this.bitmap.Size.Height) * position.Height); position.X -= (position.Width / 2); position.X = Math.Max(position.X, 0); position.X = Math.Min(position.X, this.bitmap.Size.Width - position.Width); position.Y = Math.Max(position.Y, 0); position.Y = Math.Min(position.Y, this.bitmap.Size.Height - position.Height); } } if (this.currentCropping != position) { if (Math.Abs(position.X - this.currentCropping.X) > 8 || Math.Abs(position.Width - this.currentCropping.Width) > 5) { this.currentCropping.X += Math.Min( position.X - this.currentCropping.X, this.bitmap.Size.Width / 50); this.currentCropping.Width += Math.Min( position.Width - this.currentCropping.Width, this.bitmap.Size.Width / 25); } if (Math.Abs(position.Y - this.currentCropping.Y) > 8 || Math.Abs(position.Height - this.currentCropping.Height) > 5) { this.currentCropping.Y += Math.Min( position.Y - this.currentCropping.Y, this.bitmap.Size.Height / 50); this.currentCropping.Height += Math.Min( position.Height - this.currentCropping.Height, this.bitmap.Size.Height / 25); } } if (this.currentCropping.Size != this.bitmap.Size) { using (Graphics g = Graphics.FromImage(this.bitmap)) { if (this.currentCropping != Rectangle.Empty) { g.DrawImage( this.bitmap, new Rectangle(new Point(0, 0), this.bitmap.Size), this.currentCropping, GraphicsUnit.Pixel); } g.Save(); } } if (this.softMirror) { this.bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX); } } if (!this.isIdle) { this.broadcaster.SendBitmap(this.bitmap); } this.BeginInvoke( (Action)delegate { if (!this.isIdle) { lock (this.bitmap) { if (this.pb_image.Image != null) { this.pb_image.Image.Dispose(); } this.pb_image.Image = new Bitmap(this.bitmap, this.pb_image.Size); this.pb_image.Refresh(); } } }); } } } }