using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using System; using System.Collections.Concurrent; using System.IO; using Terminal.Gui; using Color = Terminal.Gui.Color; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Images", Description: "Demonstration of how to render an image with/without true color support.")] [ScenarioCategory ("Colors")] public class Images : Scenario { public override void Setup () { base.Setup (); var x = 0; var y = 0; var canTrueColor = Application.Driver.SupportsTrueColor; var lblDriverName = new Label ($"Current driver is {Application.Driver.GetType ().Name}") { X = x, Y = y++ }; Win.Add (lblDriverName); y++; var cbSupportsTrueColor = new CheckBox ("Driver supports true color ") { X = x, Y = y++, Checked = canTrueColor, CanFocus = false }; Win.Add (cbSupportsTrueColor); var cbUseTrueColor = new CheckBox ("Use true color") { X = x, Y = y++, Checked = Application.Driver.Force16Colors, Enabled = canTrueColor, }; cbUseTrueColor.Toggled += (_, evt) => Application.Driver.Force16Colors = evt.NewValue ?? false; Win.Add (cbUseTrueColor); var btnOpenImage = new Button ("Open Image") { X = x, Y = y++ }; Win.Add (btnOpenImage); var imageView = new ImageView () { X = x, Y = y++, Width = Dim.Fill (), Height = Dim.Fill (), }; Win.Add (imageView); btnOpenImage.Clicked += (_, _) => { var ofd = new OpenDialog ("Open Image") { AllowsMultipleSelection = false }; Application.Run (ofd); if (ofd.Canceled) return; var path = ofd.FilePaths [0]; if (string.IsNullOrWhiteSpace (path)) { return; } if (!File.Exists (path)) { return; } Image img; try { img = Image.Load (File.ReadAllBytes (path)); } catch (Exception ex) { MessageBox.ErrorQuery ("Could not open file", ex.Message, "Ok"); return; } imageView.SetImage (img); }; } class ImageView : View { private Image fullResImage; private Image matchSize; ConcurrentDictionary cache = new ConcurrentDictionary (); internal void SetImage (Image image) { fullResImage = image; this.SetNeedsDisplay (); } public override void OnDrawContent(Rect bounds) { base.OnDrawContent (bounds); if (fullResImage == null) { return; } // if we have not got a cached resized image of this size if (matchSize == null || bounds.Width != matchSize.Width || bounds.Height != matchSize.Height) { // generate one matchSize = fullResImage.Clone (x => x.Resize (bounds.Width, bounds.Height)); } for (int y = 0; y < bounds.Height; y++) { for (int x = 0; x < bounds.Width; x++) { var rgb = matchSize [x, y]; var attr = cache.GetOrAdd (rgb, (rgb) => new Attribute (new Color (), new Color (rgb.R, rgb.G, rgb.B))); Driver.SetAttribute (attr); AddRune (x, y, (System.Text.Rune)' '); } } } } } }