如何在 .NET 交互式笔记本中绘制图像(C#、VS 代码)
how to draw images in a .NET Interactive notebook (C#, VS Code)
我正在尝试使用 C# 在 .NET Interactive Notebook 中绘制简单的图形。有点像 Dr. Racket 的 C# 版本。
到目前为止我见过的最简单的东西是 using System.Drawing
(SFML.NET,Raylib-cs 也可以,但是他们打开了一个 window 来显示图形而不是在笔记本)。
我也愿意尝试 #r "nuget:<whatever>"
的另一个推荐。
问题似乎与MIME类型有关,但我不确定。 .dib
和 .ipynb
得到的结果相同
有没有办法使用类似 .Display()
的东西并在笔记本中显示简单图像?
代码
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();
输出
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: [ ] }
输出 2(使用 VS 代码插件 '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"><null></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>
找到了 github 问题的答案。看起来有人也制作了 Skiasharp 扩展,这正是我正在寻找的(虽然我不知道如何安装它):
https://github.com/dotnet/interactive/issues/902#issuecomment-900918386
Updated/Fixed代码
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();
更新
我想我在尝试的过程中找到了更好的方法。 (也在 github 问题上发布了同样的内容)
...在文档和工具周围挖掘,看起来 SKSurface
Class 有一个 .Snapshot()
方法可以在笔记本中使用而无需添加任何扩展。
此外,display
命令在笔记本中似乎不再起作用。笔记本似乎有自己的 .Display()
方法。我猜是因为所有这些东西都太新了,很难找到像我这样的 n00bs 的文档?
#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();
我正在尝试使用 C# 在 .NET Interactive Notebook 中绘制简单的图形。有点像 Dr. Racket 的 C# 版本。
到目前为止我见过的最简单的东西是 using System.Drawing
(SFML.NET,Raylib-cs 也可以,但是他们打开了一个 window 来显示图形而不是在笔记本)。
我也愿意尝试 #r "nuget:<whatever>"
的另一个推荐。
问题似乎与MIME类型有关,但我不确定。 .dib
和 .ipynb
有没有办法使用类似 .Display()
的东西并在笔记本中显示简单图像?
代码
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();
输出
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: [ ] }
输出 2(使用 VS 代码插件 '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"><null></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>
找到了 github 问题的答案。看起来有人也制作了 Skiasharp 扩展,这正是我正在寻找的(虽然我不知道如何安装它):
https://github.com/dotnet/interactive/issues/902#issuecomment-900918386
Updated/Fixed代码
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();
更新
我想我在尝试的过程中找到了更好的方法。 (也在 github 问题上发布了同样的内容)
...在文档和工具周围挖掘,看起来 SKSurface
Class 有一个 .Snapshot()
方法可以在笔记本中使用而无需添加任何扩展。
此外,display
命令在笔记本中似乎不再起作用。笔记本似乎有自己的 .Display()
方法。我猜是因为所有这些东西都太新了,很难找到像我这样的 n00bs 的文档?
#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();