public static async Task ProcessFrame(Config config, MemoryStream stream, int frame, int width, int height, string outPath) { MemoryStream?resizeMemStream = null; try { stream.Seek(0, SeekOrigin.Begin); var newWidth = (int)Math.Floor(width / config.Model.ReadResolutionReduce); var newHeight = (int)Math.Floor(height / config.Model.ReadResolutionReduce); resizeMemStream = new MemoryStream(newWidth * newHeight * 4); var(zones, zoneTotals) = SetupPixelZones(newWidth, newHeight, config.Model.ZoneRows, config.Model.ZoneColumns); BitmapProcessor.ReadBitmap(stream, width, height, newWidth, newHeight, config.Model.ReadResolutionReduce, config.Model.ZoneRows, config.Model.ZoneColumns, zones, zoneTotals, 4, resizeMemStream); zoneTotals.CalculateAverages(); newWidth = (int)Math.Floor(config.Model.ZoneColumns * config.Model.ResizeScale); newHeight = (int)Math.Floor(config.Model.ZoneRows * config.Model.ResizeScale); var image = new MemoryStream(config.Model.ZoneColumns * config.Model.ZoneRows * 3); var blurImage = new MemoryStream(newWidth * newHeight * 3); (image, blurImage) = BitmapProcessor.PreparePostBitmap(zones, config.Model.ZoneColumns, config.Model.ZoneRows, newWidth, newHeight, config.Model.ResizeFilter, config.Model.ResizeSigma, image, blurImage); await ImageHandler.WriteImageToFile(blurImage, newWidth, newHeight, Path.Combine(outPath, $"out{frame.ToString().PadLeft(6, '0')}.png"), pixelFormat : PixelFormat.Rgb24); await blurImage.DisposeAsync(); await image.DisposeAsync(); foreach (var zone in zones) { zone.Dispose(); } zoneTotals.Dispose(); } catch (Exception ex) { Console.WriteLine(ex); } finally { if (resizeMemStream != null) { await resizeMemStream.DisposeAsync(); } await stream.DisposeAsync(); } }
public async Task PostRead(PixelZone[] zones, PixelZonesTotals zoneTotals, long frame) { (MemoryStream image, MemoryStream blurImage)images = (null, null); var columns = zones.OrderByDescending(x => x.Column).First().Column + 1; var rows = zones.OrderByDescending(x => x.Row).First().Row + 1; //Pre allocate the memory stream for images since it will be the same size every time if (_smallImageMemStream == null) { _smallImageMemStream = new MemoryStream(columns * rows * 3); } var newWidth = (int)Math.Floor(columns * _config.Model.zoneProcessSettings.resizeScale); var newHeight = (int)Math.Floor(rows * _config.Model.zoneProcessSettings.resizeScale); if (_blurImageMemStream == null) { _blurImageMemStream = new MemoryStream(newWidth * newHeight * 3); } try { var start = DateTime.UtcNow; var time = start; zoneTotals.CalculateAverages(); //This is for debug purpose so I can just dump out the zones as pixels //using (var smallImage = ImageHandler.CreateSmallImageFromZones(zones, columns, rows)) //{ // var path = Path.Combine(_config.Model.imageDumpLocation, $"{frame.ToString().PadLeft(6, '0')}_small.png"); // using var writeStream = File.OpenWrite(path); // smallImage.Write(writeStream, MagickFormat.Png); //} time = DateTime.UtcNow; images = BitmapProcessor.PreparePostBitmap(zones, columns, rows, newWidth, newHeight, _config.Model.zoneProcessSettings.resizeFilter, _config.Model.zoneProcessSettings.resizeSigma, _smallImageMemStream, _blurImageMemStream); //Console.WriteLine($"PreparePostBitmap Time: {(DateTime.UtcNow - time).TotalMilliseconds}"); if (images.image == null) { Console.WriteLine($"f:{frame} Image is null. Check log"); return; } Rgb24 avgColor; unsafe { int totalR = 0; int totalG = 0; int totalB = 0; for (var i = 0; i < zones.Length; ++i) { totalR += zoneTotals.AvgR[i]; totalG += zoneTotals.AvgG[i]; totalB += zoneTotals.AvgB[i]; } avgColor = new Rgb24((byte)Math.Clamp(totalR / zones.Length, 0, 255), (byte)Math.Clamp(totalG / zones.Length, 0, 255), (byte)Math.Clamp(totalB / zones.Length, 0, 255)); } time = DateTime.UtcNow; var processingTasks = new List <Task>(); if (_config.Model.hueSettings.useHue) { if (_config.Model.hueSettings.hueType == HueType.Basic) { processingTasks.Add(Task.Run(() => _hueClient.ChangeLightColorBasic(avgColor))); } else if (_config.Model.hueSettings.hueType == HueType.Entertainment) { if (_hueImageMemStream == null) { _hueImageMemStream = new MemoryStream(newWidth * newHeight * 3); } _hueImageMemStream.Seek(0, SeekOrigin.Begin); _blurImageMemStream.Seek(0, SeekOrigin.Begin); await _blurImageMemStream.CopyToAsync(_hueImageMemStream); processingTasks.Add(Task.Run(() => { _hueClient.UpdateEntertainmentGroupFromImage(_hueImageMemStream, newWidth, newHeight); })); } } if (_config.Model.lightStripSettings.useLightStrip) { if (_lstripImageMemStream == null) { _lstripImageMemStream = new MemoryStream(newWidth * newHeight * 3); } _lstripImageMemStream.Seek(0, SeekOrigin.Begin); _blurImageMemStream.Seek(0, SeekOrigin.Begin); await _blurImageMemStream.CopyToAsync(_lstripImageMemStream); processingTasks.Add(Task.Run(() => { _stripLighter.UpdateFromImage(_lstripImageMemStream, newWidth, newHeight, frame); })); } //Console.WriteLine($"PostRead ChangeLightColor Time: {(DateTime.UtcNow - time).TotalMilliseconds}"); if (!_config.Model.ffmpegCaptureSettings.useFFMpeg && (_config.Model.rgbDeviceSettings.useKeyboards || _config.Model.rgbDeviceSettings.useMice)) { if (_rgbImageMemStream == null) { _rgbImageMemStream = new MemoryStream(newWidth * newHeight * 3); } _rgbImageMemStream.Seek(0, SeekOrigin.Begin); _blurImageMemStream.Seek(0, SeekOrigin.Begin); await _blurImageMemStream.CopyToAsync(_rgbImageMemStream); processingTasks.Add(Task.Run(() => { _rgbLighter.UpdateFromImage(avgColor, _rgbImageMemStream, newWidth, newHeight); })); } if (_config.Model.dumpPngs) { try { time = DateTime.UtcNow; var path = Path.Combine(_config.Model.imageDumpLocation, $"{frame.ToString().PadLeft(6, '0')}.png"); //_ = ImageHandler.WriteImageToFile(images.image, columns, rows, path, width, height); _ = ImageHandler.WriteImageToFile(images.blurImage, newWidth, newHeight, path, pixelFormat: PixelFormat.Rgb24); //Console.WriteLine($"PostRead writeStream Time: {(DateTime.UtcNow - time).TotalMilliseconds}"); } catch (Exception ex) { _ = Task.Run(() => _logger.WriteLog(ex.ToString())); } } await Task.WhenAll(processingTasks); //Console.WriteLine($"PostRead Total Time: {(DateTime.UtcNow - start).TotalMilliseconds}"); } catch (Exception ex) { _ = Task.Run(() => _logger.WriteLog(ex.ToString())); } finally { _blurImageMemStream?.Seek(0, SeekOrigin.Begin); _smallImageMemStream?.Seek(0, SeekOrigin.Begin); _hueImageMemStream?.Seek(0, SeekOrigin.Begin); _rgbImageMemStream?.Seek(0, SeekOrigin.Begin); _lstripImageMemStream?.Seek(0, SeekOrigin.Begin); } }