5

I'm trying to draw simple graphics in the .NET Interactive Notebook, using C#. Kind of like a C# version of Dr. Racket.

The simplest thing I've seen so far is using System.Drawing (SFML.NET, Raylib-cs work too, but they open up a window to show graphics instead of within the notebook).

I'd be willing to try another recommendation with #r "nuget:<whatever>" too.

The problem seems to be related to the MIME type, but I'm not sure. I get the same results with both .dib and .ipynb

Is there a way to use something like .Display() and show the simple image within the notebook?

Code

using System.Drawing;

//Bitmap bitmap = new Bitmap(1000, 800, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Bitmap bitmap = new Bitmap(200, 200);
Graphics graphics = Graphics.FromImage(bitmap);

Pen pen = new Pen(Color.Blue, 2);
graphics.DrawArc(pen, 0, 0, 100, 100, 0, 20);

//bitmap.Save("DrawArc.png");
//display(bitmap);

bitmap.Display();

Output

Tag PhysicalDimension   Size    Width   Height  HorizontalResolution    VerticalResolution  Flags   RawFormat   PixelFormat PropertyIdList  PropertyItems   FrameDimensionsList Palette
<null>
{ {Width=200, Height=200}: IsEmpty: False, Width: 200, Height: 200 }
{ {Width=200, Height=200}: IsEmpty: False, Width: 200, Height: 200 }
200
200
96
96
2
{ MemoryBMP: Guid: b96b3caa-0728-11d3-9d7b-0000f81ef32e }
Format32bppArgb
[ ]
[ ]
[ 7462dc86-6180-4c7e-8e3f-ee7333a7a483 ]
{ System.Drawing.Imaging.ColorPalette: Flags: 0, Entries: [ ] }

Output 2 (using a VS Code Plugin 'Simple Notebook Renderers')

<table><thead><tr><th>Tag</th><th>PhysicalDimension</th><th>Size</th><th>Width</th><th>Height</th><th>HorizontalResolution</th><th>VerticalResolution</th><th>Flags</th><th>RawFormat</th><th>PixelFormat</th><th>PropertyIdList</th><th>PropertyItems</th><th>FrameDimensionsList</th><th>Palette</th></tr></thead><tbody><tr><td><div class="dni-plaintext">&lt;null&gt;</div></td><td><div class="dni-plaintext">{ {Width=200, Height=200}: IsEmpty: False, Width: 200, Height: 200 }</div></td><td><div class="dni-plaintext">{ {Width=200, Height=200}: IsEmpty: False, Width: 200, Height: 200 }</div></td><td><div class="dni-plaintext">200</div></td><td><div class="dni-plaintext">200</div></td><td><div class="dni-plaintext">96</div></td><td><div class="dni-plaintext">96</div></td><td><div class="dni-plaintext">2</div></td><td><div class="dni-plaintext">{ MemoryBMP: Guid: b96b3caa-0728-11d3-9d7b-0000f81ef32e }</div></td><td><div class="dni-plaintext">Format32bppArgb</div></td><td><div class="dni-plaintext">[  ]</div></td><td><div class="dni-plaintext">[  ]</div></td><td><div class="dni-plaintext">[ 7462dc86-6180-4c7e-8e3f-ee7333a7a483 ]</div></td><td><div class="dni-plaintext">{ System.Drawing.Imaging.ColorPalette: Flags: 0, Entries: [  ] }</div></td></tr></tbody></table>

example

user1026169
  • 5,345
  • 5
  • 21
  • 35

1 Answers1

5

Found the answer on github's issues. It looks like someone made a Skiasharp extension too, which is more what I'm looking for (although I cannot figure out how to install it):

https://github.com/dotnet/interactive/issues/902#issuecomment-900918386

Updated/Fixed Code

using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using Microsoft.DotNet.Interactive.Formatting;

MemoryStream memStream;
Bitmap bitmap = new Bitmap(200, 200);
Graphics graphics = Graphics.FromImage(bitmap);

void d()
{
    memStream = new MemoryStream();
    bitmap.Save(memStream, ImageFormat.Png);
    string base64str = Convert.ToBase64String(memStream.ToArray());
    display(PocketViewTags.img[src: "data:image/png;base64," + base64str]);
}

Pen pen = new Pen(Color.Red, 9);
graphics.DrawArc(pen, 0, 0, 100, 100, 0, 120);

d();

enter image description here

Update

I think I've found a better way while trying stuff out. (also posted the same thing over at the github issues) ...digging around the docs and tooling around, it looks like SKSurface Class has a .Snapshot() method that works in the notebook without any added extensions.

Also, the display command doesn't seem to work anymore in the notebook. The notebooks seem to have their own .Display() method. I'm guessing because all this stuff is so new its hard to find documentation for n00bs like me?

#r "nuget: SkiaSharp"
using SkiaSharp;

SKImageInfo info = new SKImageInfo(256, 256);
SKSurface surface = SKSurface.Create(info);
SKCanvas canvas = surface.Canvas;

canvas.Clear(SKColors.White);

// configure our brush
SKPaint redBrush = new SKPaint {
    Color = new SKColor(0xff, 0, 0),
    IsStroke = true
};
SKPaint blueBrush = new SKPaint {
    Color = new SKColor(0, 0, 0xff),
    IsStroke = true
};

for (int i = 0; i < 64; i += 8) {
    SKRect rect = new SKRect(i, i, 256 - i - 1, 256 - i - 1);
    canvas.DrawRect(rect, (i % 16 == 0) ? redBrush : blueBrush);
}

surface.Snapshot().Display();

enter image description here

user1026169
  • 5,345
  • 5
  • 21
  • 35