C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。
1、winform 应用程序,两个picturebox空间,一个用于视频呈现,一个用于抓拍呈现。
2、引用包OpenCvSharp4、OpenCvSharp4.Extensions、OpenCvSharp4.runtime.win等。
public partial class Form2 : Form { // 修改成员变量 private volatile Bitmap _latestFrameBitmap; private readonly object _bitmapLock = new object(); private VideoCapture _capture; private CancellationTokenSource _cts; public Form2() { InitializeComponent(); } private async void Form2_Load(object sender, EventArgs e) { _capture = new VideoCapture(0); if (!_capture.IsOpened()) { MessageBox.Show("无法打开摄像头!"); return; } _cts = new CancellationTokenSource(); try { await StartCapturingAsync(_cts.Token); } catch (OperationCanceledException) { // 正常取消 } catch (Exception ex) { MessageBox.Show($"捕获出错: {ex.Message}"); } } private async Task StartCapturingAsync(CancellationToken token) { using (var frame = new Mat()) { while (!token.IsCancellationRequested) { _capture.Read(frame); if (frame.Empty()) continue; var newBitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(frame); // 更新最新帧 lock (_bitmapLock) { var old = _latestFrameBitmap; _latestFrameBitmap = newBitmap; old?.Dispose(); } await UpdateCameraPreviewAsync(newBitmap); await Task.Delay(30, token); } } } private async Task UpdateCameraPreviewAsync(Bitmap bitmap) { if (picCamera.IsDisposed) { bitmap.Dispose(); return; } try { if (picCamera.InvokeRequired) { picCamera.BeginInvoke(new Action(() => UpdateCamera(bitmap))); } else { UpdateCamera(bitmap); } } catch (ObjectDisposedException) { bitmap.Dispose(); } } private void UpdateCamera(Bitmap newBitmap) { if (picCamera.IsDisposed) { newBitmap.Dispose(); return; } var old = picCamera.Image; picCamera.Image = newBitmap; old?.Dispose(); } // 优化后的抓拍方法 private async void catchBtn_Click(object sender, EventArgs e) { try { Bitmap snapshot = null; // 安全获取当前帧 lock (_bitmapLock) { if (_latestFrameBitmap != null) { snapshot = (Bitmap)_latestFrameBitmap.Clone(); } } if (snapshot == null) { MessageBox.Show("当前没有可用的视频帧"); return; } // 异步保存防止界面卡顿 await Task.Run(() => SaveSnapshot(snapshot)); } catch (Exception ex) { MessageBox.Show($"抓拍失败: {ex.Message}"); } } private void SaveSnapshot(Bitmap bitmap) { try { var fileName = GenerateUniqueFileName(); using (bitmap) // 确保释放资源 { bitmap.Save(fileName, ImageFormat.Jpeg); // 显示预览(需要克隆新实例) var previewBitmap = (Bitmap)bitmap.Clone(); BeginInvoke(new Action(() => { UpdateSnapshotPreview(previewBitmap); MessageBox.Show($"图片已保存到:\n{fileName}"); })); } } catch (Exception ex) { BeginInvoke(new Action(() => { MessageBox.Show($"保存失败: {ex.Message}"); })); } } // 新增预览更新方法 private void UpdateSnapshotPreview(Bitmap newBitmap) { if (pictureBoxSnapshot.IsDisposed) { newBitmap.Dispose(); return; } // 处理跨线程访问 if (pictureBoxSnapshot.InvokeRequired) { pictureBoxSnapshot.BeginInvoke(new Action(() => UpdateSnapshotPreview(newBitmap))); return; } // 更新控件并释放旧资源 var old = pictureBoxSnapshot.Image; pictureBoxSnapshot.Image = newBitmap; old?.Dispose(); } private string GenerateUniqueFileName() { var docs = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmssfff"); return Path.Combine(docs, $"Snapshot_{timestamp}.jpg"); } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { _cts?.Cancel(); _cts?.Dispose(); // 释放所有资源 _capture?.Dispose(); lock (_bitmapLock) { _latestFrameBitmap?.Dispose(); } // 清理预览图 if (picCamera.Image != null) { var img = picCamera.Image; picCamera.Image = null; img.Dispose(); } // 新增快照预览清理 if (pictureBoxSnapshot.Image != null) { var img = pictureBoxSnapshot.Image; pictureBoxSnapshot.Image = null; img.Dispose(); } } }

浙公网安备 33010602011771号