-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for the display of various image/picture types (e.g., bitmaps) #902
Comments
A custom implementation of this would be needed per .NET (base) type, so implementing this for SkiaSharp would require adding a .NET Interactive kernel extension to the SkiaSharp package. You can see examples of how this is done here: https://github.com/dotnet/interactive/tree/main/samples/extensions It might be worth supporting this out of the box for a number of common .NET types as well. |
Thanks for the pointer to the extensions! And doing some more searching, I found out how XPlot.Plotly worked out of the box with notebooks in #582. I had searched for that before making this support request, as I was curious as to how that package did it, but had missed it. I'll keep looking into the extensions, as I'd like to learn more about SkiaSharp anyway. As I understand from your comment and what I've read in the links you posted, SkiaSharp itself would take on an extension implementation addition to their package but not a package dependency on .NET Interactive. So to add this support, one would need to convince the SkiaSharp maintainers to add this extension implementation. I think SkiaSharp would probably be one of the most useful additions for built-in .NET Interactive support (through extensions). Notebooks plus graphics serve as a perfect pairing, especially for documentation of and tutorials for the library and other fun stuff. |
This is definitely something that I would want to include. My question is around the native things. How does this work? Each platform has a bunch of native files that do the rendering. Will the notebook load those as well? |
I am just playing around with this using the ClockExtension and it seems that I have to put my extension in the "lib" folder of the NuGet? If I only include it in the Is is designed to be in a separate nuget package for extensions? |
Currently, yes. We are looking at another approach though where the extension could be a polyglot script in a .dib file. |
I have just been playing around and I think this is all good. I hacked a nuget together that has 3 files:
It seems to need something in the lib folder to install since it uses the full dotnet system of packages? So if there was nothing in lib, then there was nothing to pull in. I could understand this might be an issue for extension-only packages, but we don't have this issue. That just works! Great work team! So basically, no extra work at all. No extra dependencies either. This is my full nuspec:
|
You should be able to build a simpler package that just references the SkiaSharp package rather than directly including the DLLs. |
I want to include the extension dlls in SkiaSharp (since I am the author) and don't want to have to install a special package. |
One thing I did notice with the packages, the version in the sample ClockExtension causes a runtime exception with a missing method Display in the latest stable vscode. |
How would one render images? Just convert/encode the bitmap to base64? Or is there some special way for images? |
Just a simple sample using base64 as @mattleibow mentioned and PocketView: ` MemoryStream memStream; void d() g.Clear(Color.White); g.Clear(Color.Black); should give a results like: |
In the latest previews of SkiaSharp I added some elements, but I also had to use base64. Would be cool to be able to do this automatically. And if it supports images, it might be nice for workbooks to have some basic info like size and stuff. |
Are you already creating a .NET Interactive extension that formats your types? Have a look at this extension for ImageSharp |
Just curious, would sending a MemoryStream, a Bitmap, or a Graphics object to the display function be recommended? |
Have you seen this sample your comment about the |
I had not seen the sample, thanks for sharing. I haven't dug into Graphic but just figured the other two objects I had used would be simpler to convert. |
My current implementation lives here: https://github.com/mono/SkiaSharp/tree/main/source/SkiaSharp.DotNet.Interactive |
Looks good, to make sure to have this part in your csproj
|
Hi - I'm terribly new to this whole .NET Interactive notebooks thing. I could not figure out how to get @mattleibow 's extension installed. However, digging around the docs and tooling around, it looks like Also, the
|
@rdthree SkiaSharp is a general API for drawing. For .NET Interactive notebooks, one can implement some custom formatters so that datatypes get specially displayed in the notebook (such as Plotly.NET). To get the interactive behavior, you sometimes need to reference another Nuget package (such as how Plotly.NET does it). I think @mattleibow's plan was to include the SkiaSharp extension in the already existing Nuget package, so you wouldn't need to separately reference an extension package. He added some basic support (see here and here), but I'm not sure if it got released in a Nuget release and/or if it's still current. I believe he did it as a quick trial implementation where it wasn't intended to be feature complete. I didn't know |
I long ago offered to take a look at implementing this, but that got curtailed with other stuff. However, I actually just this weekend started looking back into this and would like to take it on as a project to fully implement the SkiaSharp formatter. So, I started collecting resources. Are these the most up to date extension/formatter how-tos?
For other examples and references, I've collated:
Any other advice? I'm going to start going through everything and start trying something out. My plan is to do it in F#. |
@bmitc, those extensions docs are still current. One addition to be aware of is script-based extensions. For smaller amounts of code, this might be more sustainable because it's less likely to result in dependency conflicts. This story still has some rough edges and we'd appreciate any suggestions. And it looks like the SkiaSharp package does include the extension. When I ran @rdthree's code I saw this: |
@jonsequitur Thanks for the confirmation and the mention of the script-based extensions! Those seem like a nice middle ground where a user only has to reference a single NuGet package (at least in the case of SkiaSharp) and gets the .NET Interactive goodies without non-.NET Interactive users taking on additional dependencies (in the case of SkiaSharp not wanting a separate NuGet package for the interactive bits). I can check with @mattleibow once I get something working and understood from my side. A follow-up question is, and maybe this is a dumb one: does the script-based extension allow me to simply reference SkiaSharp in a notebook and then develop and test the extension in the notebook? Or maybe it's the case that that was already possible, and this feature just adds some automatic loading of the file as mentioned when referencing a given NuGet package? |
Yes. Anything you can run in the notebook can be put into the script in exactly the same way. You don't have to translate notebook code into project code to go from experimenting in the notebook to distributing via a package. The script will run against whatever dependencies are loaded, including the main assembly in the NuGet package. It's intended to be an alternative to the assembly-based extension approach if your code is fairly simple but it also makes automated testing and refactoring more difficult. I don't think we've found the right developer experience here yet so we'd appreciate your thoughts. |
void DisplayImage(byte[] image, string format = "jpeg", double? width = null, double? height = null) {
var base64 = Convert.ToBase64String(image);
var imageHtml = $"<img src='data:image/{format};base64,{base64}" +
(width.HasValue ? $" width='{width.Value}px'" : "") +
(height.HasValue ? $" height='{height.Value}px'" : "") +
"'/>";
imageHtml.DisplayAs("text/html");
} |
Is your feature request related to a problem? Please describe.
I would like to have images displayed in a .NET Interactive Notebook when working in Visual Studio Code with the .NET Interactive Notebooks extension. In particular, support for displaying SkiaSharp elements, such as images, bitmaps, etc. would be great.
Describe the solution you'd like
An example script might be:
Then I'd like either of
bitmap
,image
, ordata
left as the last element in the cell to have the underlying image displayed in the cell output, just as XPlot.Plotly does with its various charts and plots. The code above actually all works inside a notebook right now, and I'm able to save the image to a file. But I'd love the image to just directly appear in the cell's output.For example:
If this is possible right now, then I am not sure how to get it to happen and would love any pointers if it is possible.
Describe alternatives you've considered
I considered trying to load various views that would load external to notebook, such as using SkiaSharp.Views.Forms, Xamarin.Forms, etc. However, that's not much different than just running things in an F# script (.fsx file). Having the image immediately displayed would be fantastic for all sorts of use cases.
Edit: I edited it because I submitted by accident while creating it.
The text was updated successfully, but these errors were encountered: