From c240cb165e22a033a7ddf835784649e5abaebd68 Mon Sep 17 00:00:00 2001 From: tznind Date: Tue, 1 Oct 2024 20:44:34 +0100 Subject: [PATCH] Fix for when we want alpha pixels --- Terminal.Gui/Drawing/SixelEncoder.cs | 43 ++++++++++++++++++++++++++-- UICatalog/Scenarios/Images.cs | 41 +++++++++++++++++--------- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/Terminal.Gui/Drawing/SixelEncoder.cs b/Terminal.Gui/Drawing/SixelEncoder.cs index 77f623d27..668195736 100644 --- a/Terminal.Gui/Drawing/SixelEncoder.cs +++ b/Terminal.Gui/Drawing/SixelEncoder.cs @@ -53,7 +53,8 @@ public class SixelEncoder const string start = "\u001bP"; // Start sixel sequence - const string defaultRatios = "0;0;0"; // Defaults for aspect ratio and grid size + + string defaultRatios = this.AnyHasAlphaOfZero(pixels) ? "0;1;0": "0;0;0"; // Defaults for aspect ratio and grid size const string completeStartSequence = "q"; // Signals beginning of sixel image data const string noScaling = "\"1;1;"; // no scaling factors (1x1); @@ -146,7 +147,26 @@ public class SixelEncoder code [slots [colorIndex]] |= (byte)(1 << row); // Accumulate SIXEL data } - // TODO: Handle fully empty rows better + /* + // If no non-transparent pixels are found in the entire column, it's fully transparent + if (!anyNonTransparentPixel) + { + // Emit fully transparent pixel data: #0!?$ + result.Append ($"#0!{width}?"); + + // Add the line terminator: use "$-" if it's not the last line, "$" if it's the last line + if (x < width - 1) + { + result.Append ("$-"); + } + else + { + result.Append ("$"); + } + + // Skip to the next column as we have already handled transparency + continue; + }*/ // Handle transitions between columns for (int j = 0; j < usedColorIdx.Count; ++j) @@ -221,4 +241,23 @@ public class SixelEncoder return $"{widthInChars};{heightInChars}"; } + private bool AnyHasAlphaOfZero (Color [,] pixels) + { + int width = pixels.GetLength (0); + int height = pixels.GetLength (1); + + // Loop through each pixel in the 2D array + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + // Check if the alpha component (A) is 0 + if (pixels [x, y].A == 0) + { + return true; // Found a pixel with A of 0 + } + } + } + return false; // No pixel with A of 0 was found + } } \ No newline at end of file diff --git a/UICatalog/Scenarios/Images.cs b/UICatalog/Scenarios/Images.cs index 817e4cfa5..f873f7572 100644 --- a/UICatalog/Scenarios/Images.cs +++ b/UICatalog/Scenarios/Images.cs @@ -23,6 +23,8 @@ public class Images : Scenario private Point _screenLocationForSixel; private string _encodedSixelData; private Window _win; + private NumericUpDown _pxY; + private NumericUpDown _pxX; public override void Main () { @@ -106,15 +108,22 @@ public class Images : Scenario private void BtnStartFireOnAccept (object sender, HandledEventArgs e) { - var fire = new DoomFire (_win.Frame.Width, _win.Frame.Height); + + var fire = new DoomFire (_win.Frame.Width * _pxX.Value, _win.Frame.Height * _pxY.Value); var encoder = new SixelEncoder (); encoder.Quantizer.PaletteBuildingAlgorithm = new ConstPalette (fire.Palette); + int counter = 0; Application.AddTimeout ( - TimeSpan.FromMilliseconds (500), + TimeSpan.FromMilliseconds (30), () => { fire.AdvanceFrame (); + counter++; + if (counter % 5 != 0) + { + return true; + } var bmp = fire.GetFirePixels (); @@ -228,11 +237,10 @@ public class Images : Scenario X = Pos.Right (sixelView), Text = "Pixels per Col:" }; - - var pxX = new NumericUpDown + _pxX = new NumericUpDown { X = Pos.Right (lblPxX), - Value = 12 + Value = 10 }; var lblPxY = new Label @@ -241,18 +249,17 @@ public class Images : Scenario Y = 1, Text = "Pixels per Row:" }; - - var pxY = new NumericUpDown + _pxY = new NumericUpDown { X = Pos.Right (lblPxY), Y = 1, - Value = 6 + Value = 20 }; tabSixel.View.Add (lblPxX); - tabSixel.View.Add (pxX); + tabSixel.View.Add (_pxX); tabSixel.View.Add (lblPxY); - tabSixel.View.Add (pxY); + tabSixel.View.Add (_pxY); sixelView.DrawContent += SixelViewOnDrawContent; @@ -270,8 +277,8 @@ public class Images : Scenario _encodedSixelData = GenerateSixelData( _imageView.FullResImage, sixelView.Frame.Size, - pxX.Value, - pxY.Value); + _pxX.Value, + _pxY.Value); // TODO: Static way of doing this, suboptimal Application.Sixel.Add (new SixelToRender @@ -733,6 +740,7 @@ public class DoomFire private Color [,] _firePixels; private static Color [] _palette; public Color [] Palette => _palette; + private Random _random = new Random (); public DoomFire (int width, int height) { @@ -791,8 +799,13 @@ public class DoomFire int dstY = y - 1; // Spread fire upwards with randomness - int decay = new Random ().Next (0, 3); - int dstX = Math.Max (0, srcX - decay); + int decay = _random.Next (0, 2); + int dstX = srcX + _random.Next (-1, 2); + + if (dstX < 0 || dstX >= _width) // Prevent out of bounds + { + dstX = srcX; + } // Get the fire color from below and reduce its intensity Color srcColor = _firePixels [srcX, srcY];