I'm creating a blazor server App that should read the Webcam and show the Image, and while the Image generates fine (the base64 is completely valid) it's not updating the image on the Website even when using InvokeAsync(StateHasChanged);
Index.razor:
@page "/"
<PageTitle>Index</PageTitle>
<div style="width: 100%; height: 500px;border: solid green 1px">
<img src="@ImageSource" style="height: 100%; width: 100%; margin: auto; border: solid red 1px;"
/>
</div>
@code
{
public string? ImageSource { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
Console.WriteLine("init");
Webcam.Instance?.Init(async bufferScope =>
{
byte[] image = bufferScope.Buffer.ExtractImage();
var ms = new MemoryStream(image);
ImageSource = ToBase64Image(Bitmap.FromStream(ms));
_forceRerender = true;
await InvokeAsync(StateHasChanged);
Console.WriteLine("running again");
}, true);
}
public static string ToBase64Image(Image bmp)
{
var data = GetPng(bmp);
return "data:image/png;base64," + Convert.ToBase64String(data.ToArray());
}
public static byte[] GetPng(Image bitmap)
{
using (var stream = new MemoryStream())
{
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
bool _forceRerender = false;
protected override bool ShouldRender()
{
if (_forceRerender)
{
_forceRerender = false;
return true;
}
return base.ShouldRender();
}
}
If that helps here is my (rudimentary) webcam class (yes i know the way i have it isn't best practise but i wan't it to at least run):
using FlashCap;
namespace CameraServer.Data
{
public class Webcam
{
public static Webcam? Instance { get; private set; }
private CaptureDeviceDescriptor DeviceDescriptor { get; set; }
public CaptureDevice Device { get; private set; }
public Webcam(CaptureDeviceDescriptor deviceDescriptor)
{
DeviceDescriptor = deviceDescriptor;
Instance = this;
}
public async Task<Webcam?> Init(PixelBufferArrivedDelegate func, bool start = false)
{
Device = await DeviceDescriptor.OpenAsync(DeviceDescriptor.Characteristics[0], func);
if (start)
await Device.StartAsync();
return Instance;
}
//signal webcam to start
public void Start() => Device?.StartAsync();
//stop webcam (videoSource.WaitForStop(); to check)
public void Stop() => Device?.StopAsync();
}
}
Webcam.Instance?.Initinto a named method and using breakpoints make sure it's getting called when the webcam updates and what image you are getting.