Skip to content

Instantly share code, notes, and snippets.

@sappho192
Created May 20, 2020 09:54
Show Gist options
  • Save sappho192/b5de5a28c186c66ded04e100b41ab7da to your computer and use it in GitHub Desktop.
Save sappho192/b5de5a28c186c66ded04e100b41ab7da to your computer and use it in GitHub Desktop.
[WPF] WPF Webcam & Video player with OpenCVSharp4
<Window x:Class="WebcamCaptureApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WebcamCaptureApp"
mc:Ignorable="d"
Title="MainWindow" Height="900" Width="1600">
<Grid>
<StackPanel Orientation="Vertical">
<Image Name="imgViewport" Width="1280" Height="720"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Name="btPlay" Click="btPlay_Click" Content="Play" Width="100" Height="50" Margin="16"/>
<Button Name="btStop" Click="btStop_Click" Content="Stop" Width="100" Height="50" Margin="16"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using System;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace WebcamCaptureApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : System.Windows.Window
{
private VideoCapture capVideo;
private VideoCapture capCamera;
//private const int cameraWidth = 1920;
//private const int cameraHeight = 1080;
int sleepTime;
//private Bitmap wb = new Bitmap(videoWidth, videoHeight);
Mat matImage = new Mat();
public MainWindow()
{
InitializeComponent();
InitializeVideo();
InitializeCamera();
}
private void InitializeCamera()
{
capCamera = new VideoCapture(0);
}
private void InitializeVideo()
{
string filePath = @"D:\temp\200323.mp4";
capVideo = new VideoCapture(filePath);
sleepTime = (int)Math.Round(1000 / capVideo.Fps);
}
private void btPlay_Click(object sender, RoutedEventArgs e)
{
btPlay.IsEnabled = false;
//BackgroundWorker bw = new BackgroundWorker();
//bw.DoWork += (object sender, DoWorkEventArgs e) =>
//{
// PlayVideo();
//};
//bw.RunWorkerAsync();
//new Thread(PlayVideo).Start();
new Thread(PlayCamera).Start();
}
private void PlayCamera()
{
while (!capCamera.IsDisposed)
{
capCamera.Read(matImage); // same as cvQueryFrame
if (matImage.Empty()) break;
//Thread.Sleep(sleepTime);
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
var converted = Convert(BitmapConverter.ToBitmap(matImage));
imgViewport.Source = converted;
}));
}
}
private void PlayVideo()
{
while (!capVideo.IsDisposed)
{
capVideo.Read(matImage); // same as cvQueryFrame
if (matImage.Empty())
break;
//BitmapConverter.ToBitmap(frame, wb);
Thread.Sleep(sleepTime);
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
var converted = Convert(BitmapConverter.ToBitmap(matImage));
imgViewport.Source = converted;
}));
}
}
private void btStop_Click(object sender, RoutedEventArgs e)
{
if (capVideo.IsOpened())
{
capVideo.Dispose();
}
if (capCamera.IsOpened())
{
capCamera.Dispose();
}
btStop.IsEnabled = false;
}
public BitmapImage Convert(Bitmap src)
{
MemoryStream ms = new MemoryStream();
((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
return image;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment