using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.Kinect; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace KinectConnection { /// /// Classe représentant un flux d'image coloré pour la Kinect. /// Étend la classe KinectStream. /// public class ColorImageStream : KinectStream { /// /// The writeable bitmap. /// private WriteableBitmap bitmap = null; /// /// Obtient la source d'image de la classe. /// public override ImageSource Source { get { return this.bitmap; } } /// /// The color frame reader. /// private ColorFrameReader reader; /// /// Initialise une nouvelle instance de la classe ColorImageStream. /// public ColorImageStream() : base() { // create the colorFrameDescription from the ColorFrameSource using rgba format // the dimensions of the bitmap => match the dimensions of the color frame from the Kinect sensor. FrameDescription colorFrameDescription = this.KinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Rgba); this.bitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null); } /// /// Démarre la lecture du flux coloré. /// public override void Start() { if (this.KinectSensor != null) { this.reader = this.KinectSensor.ColorFrameSource.OpenReader(); if (this.reader != null) { this.reader.FrameArrived += this.Reader_ColorFrameArrived; } } } /// /// Arrête la lecture du flux coloré. /// public override void Stop() { if (this.reader != null) { this.reader.FrameArrived -= this.Reader_ColorFrameArrived; // Dispose the reader to free resources. // If we don't dispose manualy, the gc will do it for us, but we don't know when. this.reader.Dispose(); this.reader = null; } } /// /// Méthode appelée lors de l'arrivée d'un nouveau frame coloré. /// /// object sending the event /// event arguments private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e) { bool colorFrameProcessed = false; this.bitmap.Lock(); // ColorFrame is IDisposable // We get the frame from the event using (ColorFrame colorFrame = e.FrameReference.AcquireFrame()) { if (colorFrame != null) { // I get the frame description FrameDescription colorFrameDescription = colorFrame.FrameDescription; // verify data and write the new color frame data to the Writeable bitmap if ((colorFrameDescription.Width == this.bitmap.PixelWidth) && (colorFrameDescription.Height == this.bitmap.PixelHeight)) { // Explication du calcul : // width * height = total de pixels dans l'image // PixelFormats.Bgr32.BitsPerPixel = rapport bits/pixel // diviser par 8 pour avoir le nombre de bytes par pixel byte[] colorDataArray = new byte[colorFrameDescription.Width * colorFrameDescription.Height * ((PixelFormats.Bgr32.BitsPerPixel + 7) / 8)]; if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(colorDataArray); } else { colorFrame.CopyConvertedFrameDataToArray(colorDataArray, ColorImageFormat.Bgra); } // Write the color data to the bitmap // Int32Rect : area within the bitmap to update => in this case all this.bitmap.WritePixels( new Int32Rect(0, 0, this.bitmap.PixelWidth, this.bitmap.PixelHeight), colorDataArray, this.bitmap.PixelWidth * sizeof(int), 0); // flag that the frame was processed colorFrameProcessed = true; } } } // we got a frame, render if (colorFrameProcessed) { // ! Method not found this.bitmap.Unlock(); } } } }