C# 12.01.2019 admin No comments

Работа с вебкамерами в C#

В данной статье будет рассмотрен простой способ получения сигнала с вебкамер при помощи фреймворка Accord.NET. Также будет присутствовать функция создания фото.

Для примера создадим приложение WPF.

После создания вам необходимо будет установить через NuGet следующий пакет — Accord.Video.DirectShow. Также необходимо добавить в References библиотеку System.Drawing (References -> Add Reference… -> Assemblies).

Ниже приведён xaml код, чтобы вам не пришлось самому создавать ui, а также программный код данного окна с комментариями. Можете просто заменить данные файлы в созданном проекте.

MainWindow.xaml:

<Window x:Class="WebCam.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"
        mc:Ignorable="d"
        Closed="Window_Closed"
        Title="WebCam" Height="450" Width="800">
    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="9*"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid Grid.Row="0" Grid.Column="0">
                <ComboBox Name="ComboBoxWebcams"
                          HorizontalContentAlignment="Center"
                          VerticalContentAlignment="Center"
                          FontSize="20px"
                          SelectionChanged="ComboBoxWebcams_SelectionChanged"></ComboBox>
            </Grid>
            <Grid Grid.Row="1" Grid.Column="0">
                <Image Name="ImageWebcamFrame"
                       Margin="0,5,0,5"></Image>
            </Grid>
            <Grid Grid.Row="2" Grid.Column="0">
                <Button Name="ButtonPhoto"
                        Content="Photo"
                        FontSize="20px"
                        Click="ButtonPhoto_Click"></Button>
            </Grid>
        </Grid>
    </Grid>
</Window>

MainWindow.xaml.cs:

using Accord.Video;
using Accord.Video.DirectShow;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace WebCam
{
    public partial class MainWindow : Window
    {
        private FilterInfoCollection availableWebcams;
        private VideoCaptureDevice webcam;

        public MainWindow()
        {
            InitializeComponent();
            FillWebcams();
            SetFirstWebcam();
        }

        // метод получения всех доступных вебкамер
        private void FillWebcams()
        {
            // получаем все доступные вебкамеры
            availableWebcams = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            // добавляем их в ComboBox
            foreach (var webcam in availableWebcams)
            {
                ComboBoxWebcams.Items.Add(webcam.Name);
            }
        }

        // метод выбора первой доступной вебкамеры
        private void SetFirstWebcam()
        {
            // проверяем есть ли хоть одна вебкамера
            if (ComboBoxWebcams.Items.Count > 0)
            {
                // устанавливаем первую запись из ComboBox, в котором указан список вебкамер
                ComboBoxWebcams.SelectedIndex = 0;
            }
        }

        // метод, который останавливать предыдущую камеры и запускать выбранную в ComboBox
        private void ComboBoxWebcams_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            StopWebcam();
            StartWebcam();
        }

        // метод запуска вебкамеры
        private void StartWebcam()
        {
            // получаем объект выбранной вебкамеры
            webcam = 
                new VideoCaptureDevice(availableWebcams[ComboBoxWebcams.SelectedIndex].MonikerString);
            // запускаем её
            webcam.Start();
            // подписываемся на событие получение нового кадра
            webcam.NewFrame += new NewFrameEventHandler(webcam_NewFrame);
        }
        
        // метод остановки работы с вебкамерой
        private void StopWebcam()
        {
            if (webcam != null && webcam.IsRunning)
            {
                webcam.SignalToStop();
                webcam.NewFrame -= new NewFrameEventHandler(webcam_NewFrame);
                webcam = null;
            }
        }

        // метод, который обрабатывает полученные кадры
        private void webcam_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            // выполнение в другом потоке
            this.Dispatcher.Invoke(() =>
            {
                // переворачиваем кадр на 180 градусов, так как объект вебкамеры
                // отдаёт зеркальный кадр
                eventArgs.Frame.RotateFlip(RotateFlipType.Rotate180FlipY);
                // устанавливаем в контрол Image полученный кадр
                ImageWebcamFrame.Source = BitmapToBitmapImage(eventArgs.Frame);
            });
        }

        // метод преобразования полученного кадра, чтобы мы могли установить его в контрол
        public BitmapImage BitmapToBitmapImage(Bitmap bitmap)
        {
            using (MemoryStream memory = new MemoryStream())
            {
                bitmap.Save(memory, ImageFormat.Bmp);
                memory.Position = 0;
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();

                return bitmapImage;
            }
        }

        // метод, в котором описана логика создания фотографии
        private void ButtonPhoto_Click(object sender, RoutedEventArgs e)
        {
            // путь к папке изображений
            const string pathImageFolder = @"D:\\Photo\";
            // путь к новому изображению
            string pathToImage = string.Format("{0}{1}.png", pathImageFolder, Guid.NewGuid());

            // код дя сохранения текущего кадра в изображение в png формате
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create((BitmapSource)ImageWebcamFrame.Source));
            using(FileStream fileStream = new FileStream(pathToImage, FileMode.Create))
            {
                encoder.Save(fileStream);
            }
        }

        // перед закрытием приложения нам необходимо остановить камеру
        private void Window_Closed(object sender, EventArgs e)
        {
            StopWebcam();
        }
    }
}

Также я добавил полный готовый проект на Github.




1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (2 оценок, среднее: 5,00 из 5)
Загрузка...