Is there any way I can generate a bitmap at runtime calculating the RGBA value for each pixel and then show that bitmap on the UI in the context of using Blazor Client?
You can use ImageSharp, though it it is rather slow. Then just convert to base64 and use as <img />
source.
Note that apparently there seems to be a limit during initialization (OnInitialized/OnParametersSet/OnAfterRender
) and you won't be able to create more than 128x128x32, rendering pipeline will freeze. But if the generator code is triggered after the page has been generated, it seems to work fine with even large images. It is slow though.
ImageGeneratorBase.razor.cs
using System;
using Microsoft.AspNetCore.Components;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Primitives;
using SixLabors.Shapes;
using System.IO;
namespace StackOverflow.Sample1.Shared {
public class ImageGeneratorBase : ComponentBase {
[Parameter]
public int Width { get; set; }
[Parameter]
public int Height { get; set; }
protected string Image64 { get; set; }
public void Generate() {
using (MemoryStream outStream = new MemoryStream())
{
using (Image img = new Image<Rgba32>(Width, Height))
{
PathBuilder pathBuilder = new PathBuilder();
pathBuilder.SetOrigin(new PointF(0, 0));
pathBuilder.AddBezier(new PointF(Width / 5.0f, Height), new PointF(2 * Width / 5.0f, 0), new PointF(3 * Width / 5.0f, Height), new PointF(4 * Width / 5.0f, 0));
IPath path = pathBuilder.Build();
img.Mutate(ctx => ctx
.Fill(Color.Black)
.Draw(Color.White, 3, path)
);
img.SaveAsPng(outStream);
}
Image64 = "data:image/png;base64, " + Convert.ToBase64String(outStream.ToArray());
}
StateHasChanged();
}
}
}
ImageGenerator.razor
@inherits ImageGeneratorBase
@if (Image64 != null) {
<img src=@Image64 />
}
Index.razor
@page "/"
<p>
<Button @onclick=@(e => generator.Generate())>Generate image</Button>
</p>
<p>
<ImageGenerator Width=256 Height=256 @ref=@generator />
</p>
@code {
ImageGenerator generator;
}