WPF 检测调用电脑摄像头

 

想做一个人脸识别的软件,首先得调用电脑的摄像头,在网上搜索了一番,最多的示例都是使用AForge这个库,大多是WinForm,WPF的也有,但不够精简,整理了一下,首先Nuget如下类库:

 

准备工作:

1. 引用System.Windows.Forms / WindowsFormsIntegration / System.Drawing

2. Xaml界面添加代码

xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:aforge ="clr-namespace:AForge.Controls;assembly=AForge.Controls"

3.XAML布局

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="55"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="100"/>
    </Grid.RowDefinitions>

    <StackPanel Orientation="Horizontal">
        <Label Content="摄像头:" VerticalContentAlignment="Center" Margin="10"/>
        <ComboBox Margin="0 10" Width="160" Name="cboCamera" SelectionChanged="CboCamera_SelectionChanged" VerticalContentAlignment="Center"/>
        <Label Content="像素:" VerticalContentAlignment="Center" Margin="10"/>
        <ComboBox Margin="0 10" Width="160" Name="cboPixel" VerticalContentAlignment="Center" />
        <Button Margin="10" Content="连接" Width="80" Name="btnConnect" Click="BtnConnect_Click"/>
        <Button Margin="0 10" Content="断开" Width="80" Name="btnBreakOff" Click="BtnBreakOff_Click"/>
        <Button Margin="10" Content="拍照" Width="80" Name="btnPhotoGraph" Click="BtnPhotoGraph_Click"/>
    </StackPanel>

    <wfi:WindowsFormsHost Grid.Row="1">
        <aforge:VideoSourcePlayer x:Name="vispShoot" />
    </wfi:WindowsFormsHost>

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="2">
        <wfi:WindowsFormsHost Height="100"  Width="200">
            <aforge:PictureBox x:Name="picbPreview" BackgroundImageLayout="Zoom" />
        </wfi:WindowsFormsHost>
    </StackPanel>
</Grid>

4.后台CS代码

private FilterInfoCollection videoDevices;//所有摄像设备
private VideoCaptureDevice videoDevice;//摄像设备
private VideoCapabilities[] videoCapabilities;//摄像头分辨率
public MainWindow()
{
    InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);//得到机器所有接入的摄像设备
    if (videoDevices.Count != 0)
    {
        foreach (FilterInfo device in videoDevices)
        {
            cboCamera.Items.Add(device.Name);//把摄像设备添加到摄像列表中
        }
    }
    else
    {
        cboCamera.Items.Add("没有找到摄像头");
    }
    cboCamera.SelectedIndex = 0;//默认选择第一个
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    DisConnect();//关闭并释放
}

//连接按钮
private void BtnConnect_Click(object sender, RoutedEventArgs e)
{
    if (videoDevice != null)//如果摄像头不为空
    {
        if ((videoCapabilities != null) && (videoCapabilities.Length != 0))
        {
            videoDevice.VideoResolution = videoCapabilities[cboPixel.SelectedIndex];//摄像头分辨率
            vispShoot.VideoSource = videoDevice;//把摄像头赋给控件
            vispShoot.Start();//开启摄像头
            EnableControlStatus(false);
        }
    }
}
//断开按钮
private void BtnBreakOff_Click(object sender, RoutedEventArgs e)
{
    DisConnect();//断开连接
    EnableControlStatus(true);
}
//拍照按钮
private void BtnPhotoGraph_Click(object sender, RoutedEventArgs e)
{
    Bitmap img = vispShoot.GetCurrentVideoFrame();//拍照
    //picbPreview.Image = img;
    picbPreview.BackgroundImage = img;
    //这里可以根据情况,把照片存到某个路径下
    //img.Save("");
}

//选择摄像头改变事件
private void CboCamera_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (videoDevices.Count != 0)
    {
        //获取摄像头
        videoDevice = new VideoCaptureDevice(videoDevices[cboCamera.SelectedIndex].MonikerString);
        GetDeviceResolution(videoDevice);//获得摄像头的分辨率
    }
}
//获得摄像头的分辨率
private void GetDeviceResolution(VideoCaptureDevice videoCaptureDevice)
{
    cboPixel.Items.Clear();//清空列表
    videoCapabilities = videoCaptureDevice.VideoCapabilities;//设备的摄像头分辨率数组
    foreach (VideoCapabilities capabilty in videoCapabilities)
    {
        //把这个设备的所有分辨率添加到列表
        cboPixel.Items.Add($"{capabilty.FrameSize.Width} x {capabilty.FrameSize.Height}");
    }
    cboPixel.SelectedIndex = cboPixel.Items.Count - 1;//默认选择最后一个(分辨率最大)
}

//控件的显示切换
private void EnableControlStatus(bool status)
{
    cboCamera.IsEnabled = status;
    cboPixel.IsEnabled = status;
    btnConnect.IsEnabled = status;
    btnBreakOff.IsEnabled = !status;
    btnPhotoGraph.IsEnabled = !status;
}
//关闭并释放
private void DisConnect()
{
    if (vispShoot.VideoSource != null)
    {
        vispShoot.SignalToStop();
        vispShoot.WaitForStop();
        vispShoot.VideoSource = null;
    }
} 
 
 

效果图:

 

相关推荐

网友评论(0)