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(); } }); }
/// <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(); }
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(); }
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(); } }
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(); } } }); }
/// <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"); }
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(); }
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(); }
/// <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(); }
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(); }
/// <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(); } }
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; }