You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server调用StateHasChanged()后摄像头图片仍不更新求助

Blazor Server摄像头图像不更新问题修复

问题排查方向

你的Base64图像有效但页面不更新,主要可能出在渲染触发逻辑、资源释放或回调上下文这几个点:

  • 自定义的ShouldRender逻辑可能意外阻止了渲染;
  • 回调中未正确释放Bitmap和MemoryStream,导致内存泄漏或图像数据异常;
  • FlashCap的回调线程上下文与Blazor同步上下文不匹配,InvokeAsync的执行时机有问题。

分步修复方案

1. 移除不必要的ShouldRender限制

Blazor Server中调用InvokeAsync(StateHasChanged)本身就会触发组件重新渲染,自定义ShouldRender的条件反而可能抑制正常渲染。先去掉这部分代码:

@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();
            // 使用using自动释放资源,避免内存泄漏
            using var ms = new MemoryStream(image);
            using var bmp = Bitmap.FromStream(ms);
            ImageSource = ToBase64Image(bmp);
            await InvokeAsync(StateHasChanged);
            Console.WriteLine("running again");
        }, true);
    }

    public static string ToBase64Image(Image bmp)
    {
        using var stream = new MemoryStream();
        bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        return "data:image/png;base64," + Convert.ToBase64String(stream.ToArray());
    }
}

2. 修复Webcam类的异步方法调用

原Webcam类的Start和Stop方法调用异步方法却未等待,可能导致摄像头启动/停止逻辑异常:

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;
        }

        // 改为异步方法并等待
        public async Task Start() => await Device?.StartAsync()!;
        public async Task Stop() => await Device?.StopAsync()!;
    }
}

3. 可选:绕过浏览器缓存

如果浏览器缓存了初始图像,即使src更新也不刷新,可以给Base64 URL添加随机参数:

ImageSource = $"data:image/png;base64,{Convert.ToBase64String(stream.ToArray())}?t={DateTime.Now.Ticks}";

验证方法

  1. 启动应用后,查看控制台是否持续输出"running again",确认回调在正常触发;
  2. 打开浏览器开发者工具,检查<img>标签的src属性是否持续变化;
  3. 若src变化但图像未更新,添加上述随机参数验证是否为缓存问题。

内容的提问来源于stack exchange,提问作者juffma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:35:26