C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。
生活随笔
收集整理的這篇文章主要介紹了
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();
}
}
}
總結
以上是生活随笔為你收集整理的C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用命令——ls tree 文件
- 下一篇: jsoncpp 构造空数组