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

在.NET MAUI中使用OpenCV实现相机预览与录像的问题求助

.NET MAUI + OpenCV 相机预览&录像问题修复

核心问题分析

  1. 应用冻结:你把整个录像循环放在UI线程里执行,再加上Cv2.WaitKey直接阻塞了主线程,UI自然会卡死。
  2. 预览不显示:一是UI线程被阻塞无法更新控件;二是MemoryStream保存图片后未重置读取位置,控件读不到流内容;三是更新UI控件的操作没有在主线程执行。

修复方案

1. 把录像逻辑移到后台线程

用Task.Run启动后台任务,避免占用UI线程导致冻结。

2. 强制在主线程更新UI

MAUI中所有UI操作必须在主线程执行,用MainThread.BeginInvokeOnMainThread包裹UI更新代码。

3. 修正流读取问题

图片保存到MemoryStream后,设置stream.Position = 0,否则控件读取流时会从末尾开始,拿不到有效数据。

4. 替换Cv2.WaitKey

MAUI是跨平台框架,Cv2.WaitKey仅适用于WinForms/WPF场景,改用Task.Delay控制帧率,更符合.NET MAUI的异步模型。

修改后的代码

// 启动后台任务执行录像逻辑
await Task.Run(async () =>
{
    using (VideoCapture capture = new VideoCapture(0))
    {
        capture.Set(VideoCaptureProperties.Fps, 30.0);
        OpenCvSharp.Size dsize = new OpenCvSharp.Size(capture.FrameWidth, capture.FrameHeight);
        
        using (VideoWriter writer = new VideoWriter($"C:/tmp/{tracking_num}.avi", four, capture.Fps, dsize, true))
        using (Mat frame = new Mat())
        {
            while (recording)
            {
                if (!capture.Read(frame) || frame.Empty())
                    break;

                // 转换帧并更新UI,必须在主线程执行
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    using (Bitmap bitimg = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(frame))
                    using (MemoryStream stream = new MemoryStream())
                    {
                        bitimg.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        stream.Position = 0; // 重置流位置,确保控件能读到数据
                        video_display.Source = ImageSource.FromStream(() => stream);
                    }
                });

                writer.Write(frame);

                // 用Task.Delay替代WaitKey,控制帧率
                if (capture.Fps > 0)
                {
                    await Task.Delay(TimeSpan.FromMilliseconds(1000 / capture.Fps));
                }
                else
                {
                    await Task.Delay(1);
                }
            }
        }
    }
});

额外注意事项

  • 确保recording变量线程安全,可使用volatile修饰,或通过Interlocked类操作,避免多线程读写冲突。
  • 配置平台权限:MAUI访问相机和存储需要在对应平台项目中配置权限(比如Android的CAMERA、WRITE_EXTERNAL_STORAGE;iOS的NSCameraUsageDescription、NSPhotoLibraryAddUsageDescription)。
  • 可尝试更高效的帧转换方式,比如直接转成SKBitmap(依赖SkiaSharp),减少Bitmap转换的性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:15:20