mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add canvas and image support
Adds support for drawing "pixels" and displaying images in the terminal.
This commit is contained in:

committed by
Patrik Svensson

parent
4f6eca4fcb
commit
2a9fa223de
22
examples/Canvas/Canvas.csproj
Normal file
22
examples/Canvas/Canvas.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Canvas</Title>
|
||||
<Description>Demonstrates how to render pixels and images.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj" />
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="cake.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
87
examples/Canvas/Mandelbrot.cs
Normal file
87
examples/Canvas/Mandelbrot.cs
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Ported from: https://rosettacode.org/wiki/Mandelbrot_set#C.23
|
||||
Licensed under GNU Free Documentation License 1.2
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace CanvasExample
|
||||
{
|
||||
public static class Mandelbrot
|
||||
{
|
||||
private const double MaxValueExtent = 2.0;
|
||||
|
||||
private struct ComplexNumber
|
||||
{
|
||||
public double Real { get; }
|
||||
public double Imaginary { get; }
|
||||
|
||||
public ComplexNumber(double real, double imaginary)
|
||||
{
|
||||
Real = real;
|
||||
Imaginary = imaginary;
|
||||
}
|
||||
|
||||
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
return new ComplexNumber(x.Real + y.Real, x.Imaginary + y.Imaginary);
|
||||
}
|
||||
|
||||
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
return new ComplexNumber(x.Real * y.Real - x.Imaginary * y.Imaginary,
|
||||
x.Real * y.Imaginary + x.Imaginary * y.Real);
|
||||
}
|
||||
|
||||
public double Abs()
|
||||
{
|
||||
return Real * Real + Imaginary * Imaginary;
|
||||
}
|
||||
}
|
||||
|
||||
public static Canvas Generate(int width, int height)
|
||||
{
|
||||
var canvas = new Canvas(width, height);
|
||||
|
||||
var scale = 2 * MaxValueExtent / Math.Min(canvas.Width, canvas.Height);
|
||||
for (var i = 0; i < canvas.Height; i++)
|
||||
{
|
||||
var y = (canvas.Height / 2 - i) * scale;
|
||||
for (var j = 0; j < canvas.Width; j++)
|
||||
{
|
||||
var x = (j - canvas.Width / 2) * scale;
|
||||
var value = Calculate(new ComplexNumber(x, y));
|
||||
canvas.SetPixel(j, i, GetColor(value));
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
private static double Calculate(ComplexNumber c)
|
||||
{
|
||||
const int MaxIterations = 1000;
|
||||
const double MaxNorm = MaxValueExtent * MaxValueExtent;
|
||||
|
||||
var iteration = 0;
|
||||
var z = new ComplexNumber();
|
||||
do
|
||||
{
|
||||
z = z * z + c;
|
||||
iteration++;
|
||||
} while (z.Abs() < MaxNorm && iteration < MaxIterations);
|
||||
|
||||
return iteration < MaxIterations
|
||||
? (double)iteration / MaxIterations
|
||||
: 0;
|
||||
}
|
||||
|
||||
private static Color GetColor(double value)
|
||||
{
|
||||
const double MaxColor = 256;
|
||||
const double ContrastValue = 0.2;
|
||||
return new Color(0, 0, (byte)(MaxColor * Math.Pow(value, ContrastValue)));
|
||||
}
|
||||
}
|
||||
}
|
36
examples/Canvas/Program.cs
Normal file
36
examples/Canvas/Program.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace CanvasExample
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Draw a mandelbrot set using a Canvas
|
||||
var mandelbrot = Mandelbrot.Generate(32, 32);
|
||||
Render(mandelbrot, "Mandelbrot");
|
||||
|
||||
// Draw an image using CanvasImage powered by ImageSharp.
|
||||
// This requires the "Spectre.Console.ImageSharp" NuGet package.
|
||||
var image = new CanvasImage("cake.png");
|
||||
image.BilinearResampler();
|
||||
image.MaxWidth(16);
|
||||
Render(image, "Image from file (16 wide)");
|
||||
|
||||
// Draw image again, but without render width
|
||||
image.NoMaxWidth();
|
||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||
}
|
||||
|
||||
private static void Render(IRenderable canvas, string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule($"[yellow]{title}[/]").LeftAligned().RuleStyle("grey"));
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(canvas);
|
||||
}
|
||||
}
|
||||
}
|
BIN
examples/Canvas/cake.png
Normal file
BIN
examples/Canvas/cake.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
@ -7,34 +7,34 @@ namespace EmojiExample
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// No title
|
||||
WrapInPanel(
|
||||
Render(
|
||||
new Rule()
|
||||
.RuleStyle(Style.Parse("yellow"))
|
||||
.AsciiBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Left aligned title
|
||||
WrapInPanel(
|
||||
Render(
|
||||
new Rule("[blue]Left aligned[/]")
|
||||
.RuleStyle(Style.Parse("red"))
|
||||
.DoubleBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Centered title
|
||||
WrapInPanel(
|
||||
Render(
|
||||
new Rule("[green]Centered[/]")
|
||||
.RuleStyle(Style.Parse("green"))
|
||||
.HeavyBorder()
|
||||
.Centered());
|
||||
|
||||
// Right aligned title
|
||||
WrapInPanel(
|
||||
Render(
|
||||
new Rule("[red]Right aligned[/]")
|
||||
.RuleStyle(Style.Parse("blue"))
|
||||
.RightAligned());
|
||||
}
|
||||
|
||||
private static void WrapInPanel(Rule rule)
|
||||
private static void Render(Rule rule)
|
||||
{
|
||||
AnsiConsole.Render(rule);
|
||||
AnsiConsole.WriteLine();
|
||||
|
Reference in New Issue
Block a user