Пример #1
0
        public async void UpdateChunk(Chunk chunk)
        {
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                lock (Bitmap)
                {
                    Bitmap.Lock();

                    var backbuffer = Bitmap.BackBuffer;
                    var stride     = Bitmap.BackBufferStride;

                    unsafe
                    {
                        for (var y = chunk.StartY; y < chunk.StartY + chunk.Height; ++y)
                        {
                            for (var x = 0; x < chunk.Width; ++x)
                            {
                                var writeAddress = backbuffer + x * 4 + y * stride;
                                var floatColor   = Scene.ColorData[x, y];

                                floatColor.Red   /= Scene.SampleCount[x, y];
                                floatColor.Green /= Scene.SampleCount[x, y];
                                floatColor.Blue  /= Scene.SampleCount[x, y];

                                var color = Min((int)(floatColor.Blue * 255.0f), 255) | (Min((int)(floatColor.Green * 255.0f), 255) << 8) | (Min((int)(floatColor.Red * 255.0f), 255) << 16);
                                *((int *)writeAddress) = color;
                            }
                        }
                    }

                    Bitmap.AddDirtyRect(new Int32Rect(0, chunk.StartY, chunk.Width, chunk.Height));
                    Bitmap.Unlock();
                }
            });
        }
Пример #2
0
        /// <summary>
        /// https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.writeablebitmap?redirectedfrom=MSDN&view=netframework-4.8
        /// </summary>
        public void SetPixel(int x, int y, int color)
        {
            if (Bitmap == null)
            {
                return;
            }

            bool isValid = x >= 0 && y >= 0 && x < Bitmap.PixelWidth && y < Bitmap.PixelHeight;

            if (!isValid)
            {
                return;
            }


            Bitmap.Lock();

            unsafe
            {
                IntPtr backBuffer = Bitmap.BackBuffer;

                backBuffer += y * Bitmap.BackBufferStride;
                backBuffer += x * 4;

                *(int *)backBuffer = color;
            }

            Bitmap.AddDirtyRect(new Int32Rect(x, y, 1, 1));
            Bitmap.Unlock();
        }
        public override void Apply(int Kr, int Kg, int Kb)
        {
            int nR = ComputeN(Kr);
            int nG = ComputeN(Kg);
            int nB = ComputeN(Kb);

            int itR = 255 / (Kr - 1);
            int itG = 255 / (Kg - 1);
            int itB = 255 / (Kb - 1);

            Bitmap.Lock();
            unsafe
            {
                int   copyIt  = 0;
                byte *currPos = (byte *)Bitmap.BackBuffer.ToPointer();
                for (int i = 0; i < height; ++i)
                {
                    for (int j = 0; j < width; ++j)
                    {
                        currPos[0] = ComputePixel(copyIt, nB, itB, i, j, 0);
                        currPos[1] = ComputePixel(copyIt, nG, itG, i, j, 1);
                        currPos[2] = ComputePixel(copyIt, nR, itR, i, j, 2);

                        currPos += bytesPerPixel;
                        copyIt  += bytesPerPixel;
                    }
                }
            }
            Bitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
            Bitmap.Unlock();
        }
Пример #4
0
        public override void Apply(int Kr, int Kg, int Kb)
        {
            int itR = 255 / (Kr - 1);
            int itG = 255 / (Kg - 1);
            int itB = 255 / (Kb - 1);

            Bitmap.Lock();
            unsafe
            {
                int   copyIt  = 0;
                byte *currPos = (byte *)Bitmap.BackBuffer.ToPointer();
                for (int i = 0; i < height; ++i)
                {
                    for (int j = 0; j < width; ++j)
                    {
                        currPos[0] = RoundToNeareastMultiple(originalCopy[copyIt], itB).ToByte();
                        currPos[1] = RoundToNeareastMultiple(originalCopy[copyIt + 1], itG).ToByte();
                        currPos[2] = RoundToNeareastMultiple(originalCopy[copyIt + 2], itR).ToByte();

                        currPos += bytesPerPixel;
                        copyIt  += bytesPerPixel;
                    }
                }
            }
            Bitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
            Bitmap.Unlock();
        }
Пример #5
0
    protected override void Render(int xStart, int yStart, int width, int height)
    {
        try
        {
            if (!Bitmap.TryLock(new System.Windows.Duration(TimeSpan.FromMilliseconds(500))))
            {
                throw new TimeoutException($"{nameof(IndexedBitmapAdapter)}.{nameof(Render)} could not lock the Bitmap for rendering");
            }

            unsafe
            {
                var backBuffer = (uint *)Bitmap.BackBuffer.ToPointer();
                var stride     = Bitmap.BackBufferStride;

                Parallel.For(yStart, yStart + height, (scanline) =>
                {
                    var dest = backBuffer + scanline * stride / 4 + xStart;
                    var src  = Image.GetPixelRowSpan(scanline);

                    for (int x = 0; x < width; x++)
                    {
                        dest[x] = TranslateColor(x + xStart, scanline, src);
                    }
                });
            }

            Bitmap.AddDirtyRect(new System.Windows.Int32Rect(xStart, yStart, width, height));
        }
        finally
        {
            Bitmap.Unlock();
        }
    }
Пример #6
0
        public async void UpdateChunk(Chunk chunk, byte[] colorData)
        {
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                using (var memoryStream = new MemoryStream(colorData))
                    using (var binaryReader = new BinaryReader(memoryStream))
                    {
                        lock (Bitmap)
                        {
                            Bitmap.Lock();

                            var backbuffer = Bitmap.BackBuffer;
                            var stride     = Bitmap.BackBufferStride;

                            unsafe
                            {
                                for (var y = chunk.StartY; y < chunk.StartY + chunk.Height; ++y)
                                {
                                    for (var x = 0; x < chunk.Width; ++x)
                                    {
                                        var writeAddress       = backbuffer + x * 4 + y * stride;
                                        int color              = binaryReader.ReadInt32();
                                        *((int *)writeAddress) = color;
                                    }
                                }
                            }

                            Bitmap.AddDirtyRect(new Int32Rect(0, chunk.StartY, chunk.Width, chunk.Height));
                            Bitmap.Unlock();
                        }
                    }
            });
        }
Пример #7
0
        /// <summary>
        /// Generate bitmap with result of the algorithm. Called from Background Worker.
        /// </summary>
        /// <param name="sender">Object that calls this method.</param>
        /// <param name="e">Event arguments.</param>
        private void UpdateBitmap(object sender, RunWorkerCompletedEventArgs e)
        {
            byte[] rawImage = (byte[])e.Result;
            Bitmap.Lock();
            Int32Rect rect = new Int32Rect(0, 0, Width, Height);

            Bitmap.WritePixels(rect, rawImage, _data.stride, 0);
            Bitmap.AddDirtyRect(rect);
            Bitmap.Unlock();
            NotifyPropertyChanged("Bitmap");
        }
Пример #8
0
        public void Render(Action <Bitmap> renderer, Int32Rect rect)
        {
            renderer.AssertNotNull(nameof(renderer));

            Bitmap.Lock();

            using (var target = CreateRenderTargetBitmap())
            {
                renderer(target);
            }

            Bitmap.AddDirtyRect(rect);
            Bitmap.Unlock();
        }
Пример #9
0
        public void Update()
        {
            Bitmap.Lock();

            using (SKSurface surface = SKSurface.Create(Width, Height, SKColorType.Bgra8888, SKAlphaType.Premul, Bitmap.BackBuffer, Width * 4))
            {
                SKCanvas canvas = surface.Canvas;
                canvas.Clear();
                Draw(canvas);
            }

            Bitmap.AddDirtyRect(new Int32Rect(0, 0, Width, Height));

            Bitmap.Unlock();
        }
Пример #10
0
        /// <summary>
        /// Updates the bitmap with new frame data.
        /// </summary>
        /// <param name="frame">The specified Kinect depth frame.</param>
        public void Update(DepthFrame frame)
        {
            ushort minDepth = frame.DepthMinReliableDistance;
            ushort maxDepth = frame.DepthMaxReliableDistance;

            if (Bitmap == null)
            {
                Width     = frame.FrameDescription.Width;
                Height    = frame.FrameDescription.Height;
                DepthData = new ushort[Width * Height];
                Pixels    = new byte[Width * Height * Constants.BYTES_PER_PIXEL];
                Bitmap    = new WriteableBitmap(Width, Height, Constants.DPI, Constants.DPI, Constants.FORMAT, null);
            }

            frame.CopyFrameDataToArray(DepthData);

            // Convert the depth to RGB.
            int colorIndex = 0;

            for (int depthIndex = 0; depthIndex < DepthData.Length; ++depthIndex)
            {
                // Get the depth for this pixel
                ushort depth = DepthData[depthIndex];

                // To convert to a byte, we're discarding the most-significant
                // rather than least-significant bits.
                // We're preserving detail, although the intensity will "wrap."
                // Values outside the reliable depth range are mapped to 0 (black).
                byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0);

                Pixels[colorIndex++] = intensity; // Blue
                Pixels[colorIndex++] = intensity; // Green
                Pixels[colorIndex++] = intensity; // Red

                // We're outputting BGR, the last byte in the 32 bits is unused so skip it
                // If we were outputting BGRA, we would write alpha here.
                ++colorIndex;
            }

            Bitmap.Lock();

            Marshal.Copy(Pixels, 0, Bitmap.BackBuffer, Pixels.Length);
            Bitmap.AddDirtyRect(new Int32Rect(0, 0, Width, Height));

            Bitmap.Unlock();
        }
Пример #11
0
        public void SetPixels(int x, int y, Color[,] colors)
        {
            if (Bitmap == null)
            {
                return;
            }

            int width  = colors.GetLength(0);
            int height = colors.GetLength(1);

            bool isValid = x >= 0 && y >= 0 && x + width < Bitmap.PixelWidth && y + height < Bitmap.PixelHeight;

            if (!isValid)
            {
                return;
            }


            Bitmap.Lock();

            unsafe
            {
                IntPtr backBuffer = Bitmap.BackBuffer;

                const int pixel = sizeof(int);

                backBuffer += y * (Bitmap.PixelWidth * pixel);
                backBuffer += x * pixel - pixel;

                int newLineOffset = (Bitmap.PixelWidth - width) * pixel;

                for (int localY = 0; localY < height; localY++)
                {
                    for (int localX = 0; localX < width; localX++)
                    {
                        backBuffer        += pixel;
                        *(int *)backBuffer = (int)colors[localX, localY];
                    }

                    backBuffer += newLineOffset;
                }
            }

            Bitmap.AddDirtyRect(new Int32Rect(x, y, width, height));
            Bitmap.Unlock();
        }
        /// <summary>
        /// Updates the bitmap with new frame data.
        /// </summary>
        /// <param name="frame">The specified Kinect color frame.</param>
        public override void Update(ColorFrame frame)
        {
            if (Bitmap == null)
            {
                Width  = frame.FrameDescription.Width;
                Height = frame.FrameDescription.Height;
                Pixels = new byte[Width * Height * Constants.BYTES_PER_PIXEL];
                Bitmap = new WriteableBitmap(Width, Height, Constants.DPI, Constants.DPI, Constants.FORMAT, null);
            }

            frame.CopyConvertedFrameDataToArray(Pixels, ColorImageFormat.Bgra);

            Bitmap.Lock();

            Marshal.Copy(Pixels, 0, Bitmap.BackBuffer, Pixels.Length);
            Bitmap.AddDirtyRect(new Int32Rect(0, 0, Width, Height));

            Bitmap.Unlock();
        }
Пример #13
0
        /// <summary>
        /// Updates the bitmap with new frame data.
        /// </summary>
        /// <param name="frame">The specified Kinect infrared frame.</param>
        public override void Update(InfraredFrame frame)
        {
            if (Bitmap == null)
            {
                Width        = frame.FrameDescription.Width;
                Height       = frame.FrameDescription.Height;
                InfraredData = new ushort[Width * Height];
                Pixels       = new byte[Width * Height * Constants.BYTES_PER_PIXEL];
                Bitmap       = new WriteableBitmap(Width, Height, Constants.DPI, Constants.DPI, Constants.FORMAT, null);
            }

            frame.CopyFrameDataToArray(InfraredData);

            // Convert the infrared to RGB.
            int colorIndex = 0;

            for (int infraredIndex = 0; infraredIndex < InfraredData.Length; infraredIndex++)
            {
                // Get the infrared value for this pixel
                ushort ir = InfraredData[infraredIndex];

                // To convert to a byte, we're discarding the most-significant
                // rather than least-significant bits.
                // We're preserving detail, although the intensity will "wrap."
                byte intensity = (byte)(ir >> 6);

                Pixels[colorIndex++] = intensity; // Blue
                Pixels[colorIndex++] = intensity; // Green
                Pixels[colorIndex++] = intensity; // Red

                // We're outputting BGR, the last byte in the 32 bits is unused so skip it
                // If we were outputting BGRA, we would write alpha here.
                colorIndex++;
            }

            Bitmap.Lock();

            Marshal.Copy(Pixels, 0, Bitmap.BackBuffer, Pixels.Length);
            Bitmap.AddDirtyRect(new Int32Rect(0, 0, Width, Height));

            Bitmap.Unlock();
        }
        /// <summary>
        /// Updates the bitmap with new frame data.
        /// </summary>
        /// <param name="depthFrame">The specified depth frame.</param>
        /// <param name="colorFrame">The specified color frame.</param>
        /// <param name="bodyIndexFrame">The specified body index frame.</param>
        public void Update(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame)
        {
            int colorWidth  = colorFrame.FrameDescription.Width;
            int colorHeight = colorFrame.FrameDescription.Height;

            int depthWidth  = depthFrame.FrameDescription.Width;
            int depthHeight = depthFrame.FrameDescription.Height;

            int bodyIndexWidth  = bodyIndexFrame.FrameDescription.Width;
            int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height;

            if (_displayPixels == null)
            {
                _depthData     = new ushort[depthWidth * depthHeight];
                _bodyData      = new byte[depthWidth * depthHeight];
                _colorData     = new byte[colorWidth * colorHeight * Constants.BYTES_PER_PIXEL];
                _displayPixels = new byte[depthWidth * depthHeight * Constants.BYTES_PER_PIXEL];
                _colorPoints   = new ColorSpacePoint[depthWidth * depthHeight];
                Bitmap         = new WriteableBitmap(depthWidth, depthHeight, Constants.DPI, Constants.DPI, Constants.FORMAT, null);
            }

            if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * Constants.BYTES_PER_PIXEL) == _colorData.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length))
            {
                depthFrame.CopyFrameDataToArray(_depthData);

                if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra)
                {
                    colorFrame.CopyRawFrameDataToArray(_colorData);
                }
                else
                {
                    colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra);
                }

                bodyIndexFrame.CopyFrameDataToArray(_bodyData);

                CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints);

                Array.Clear(_displayPixels, 0, _displayPixels.Length);

                for (int y = 0; y < depthHeight; ++y)
                {
                    for (int x = 0; x < depthWidth; ++x)
                    {
                        int depthIndex = (y * depthWidth) + x;

                        byte player = _bodyData[depthIndex];

                        if (player != 0xff)
                        {
                            ColorSpacePoint colorPoint = _colorPoints[depthIndex];

                            int colorX = (int)Math.Floor(colorPoint.X + 0.5);
                            int colorY = (int)Math.Floor(colorPoint.Y + 0.5);

                            if ((colorX >= 0) && (colorX < colorWidth) && (colorY >= 0) && (colorY < colorHeight))
                            {
                                int colorIndex   = ((colorY * colorWidth) + colorX) * Constants.BYTES_PER_PIXEL;
                                int displayIndex = depthIndex * Constants.BYTES_PER_PIXEL;

                                _displayPixels[displayIndex + 0] = _colorData[colorIndex];
                                _displayPixels[displayIndex + 1] = _colorData[colorIndex + 1];
                                _displayPixels[displayIndex + 2] = _colorData[colorIndex + 2];
                                _displayPixels[displayIndex + 3] = 0xff;
                            }
                        }
                    }
                }

                Bitmap.Lock();

                Marshal.Copy(Pixels, 0, Bitmap.BackBuffer, _displayPixels.Length);
                Bitmap.AddDirtyRect(new Int32Rect(0, 0, Width, Height));

                Bitmap.Unlock();
            }
        }
Пример #15
0
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            int clustersPerSquare = Math.Max(1, Configuration.Geometry.DataClustersPerTrack / nHorizontalSquaresGoal);

            int nDataSquares   = (Configuration.Geometry.DataClustersPerTrack + clustersPerSquare - 1) / clustersPerSquare;
            int nParitySquares = (Configuration.Geometry.ParityClustersPerTrack + clustersPerSquare - 1) / clustersPerSquare;
            int nSquares       = nDataSquares + nParitySquares;

            cts = new CancellationTokenSource();
            cancelButton.IsEnabled          = true;
            calculateParityButton.IsEnabled = false;

            for (int i = 0; i < Configuration.Geometry.TrackCount && !cts.IsCancellationRequested; i++)
            {
                Track t = _data.GetTrack(i);
                if (!t.UpToDate)
                {
                    Track.UpdateParityStatus status = new Track.UpdateParityStatus();
                    void h(object s2, PropertyChangedEventArgs e2)
                    {
                        Dispatcher.Invoke(() => {
                            Color color;
                            int clusterFinished = status.Cluster;
                            int c = 0;
                            if (clusterFinished < Configuration.Geometry.DataClustersPerTrack)
                            {
                                color = Colors.LightGreen;
                                if (clusterFinished % clustersPerSquare == clustersPerSquare - 1)
                                {
                                    c = clusterFinished / clustersPerSquare;
                                }
                                else if (clusterFinished == Configuration.Geometry.DataClustersPerTrack - 1)
                                {
                                    c = nDataSquares - 1;
                                }
                                else
                                {
                                    return;
                                }
                            }
                            else
                            {
                                clusterFinished -= Configuration.Geometry.DataClustersPerTrack;
                                color            = Colors.Blue;
                                if (clusterFinished % clustersPerSquare == clustersPerSquare - 1)
                                {
                                    c = nDataSquares + clusterFinished / clustersPerSquare;
                                }
                                else if (clusterFinished == Configuration.Geometry.ParityClustersPerTrack - 1)
                                {
                                    c = nDataSquares + nParitySquares - 1;
                                }
                                else
                                {
                                    return;
                                }
                            }

                            Bitmap.Lock();
                            Bitmap.FillRectangle(
                                c * squareSize + 1, i * squareSize + 1,
                                c * squareSize + squareSize, i * squareSize + squareSize,
                                color);
                            Bitmap.AddDirtyRect(new Int32Rect(c * squareSize + 1, i * squareSize + 1, squareSize - 1, squareSize - 1));
                            Bitmap.Unlock();
                        });
                    }

                    status.PropertyChanged += h;
                    await t.UpdateParity(false, status, cts.Token);

                    if (cts.IsCancellationRequested)
                    {
                        Bitmap.Lock();

                        int c = 0;
                        foreach (var a in t.DataClusters.Batch(clustersPerSquare))
                        {
                            Color color;
                            if (a.Any(x => !_data.GetClusterState(x).IsSystem() && _data.GetClusterState(x).IsModified()))
                            {
                                color = Colors.Red;
                            }
                            else if (a.Any(x => _data.GetClusterState(x).IsUsed()))
                            {
                                color = Colors.LightGreen;
                            }
                            else if (a.Any(x => _data.GetClusterState(x).IsSystem()))
                            {
                                color = Colors.Violet;
                            }
                            else
                            {
                                color = Colors.Gray;
                            }

                            Bitmap.FillRectangle(c * squareSize + 1, i * squareSize + 1, c * squareSize + squareSize, i * squareSize + squareSize, color);
                            c++;
                        }
                        foreach (var a in t.ParityClusters.Batch(clustersPerSquare))
                        {
                            Color color;
                            if (a.All(x => !_data.GetClusterState(x).IsUnwritten()))
                            {
                                color = Colors.Blue;
                            }
                            else
                            {
                                color = Colors.Gray;
                            }

                            Bitmap.FillRectangle(c * squareSize + 1, i * squareSize + 1, c * squareSize + squareSize, i * squareSize + squareSize, color);
                            c++;
                        }

                        Bitmap.AddDirtyRect(new Int32Rect(0, i * squareSize + 1, nSquares * squareSize + 1, squareSize - 1));
                        Bitmap.Unlock();
                    }
                    else
                    {
                        _data.ProtectedTrackCount++;
                    }
                    status.PropertyChanged -= h;
                }
            }

            calculateParityButton.IsEnabled = true;
            cancelButton.IsEnabled          = false;
        }