zoukankan      html  css  js  c++  java
  • 用wpf实现显示摄像头画面,并且能拍照,标注,切换画面等等

    1、能拍照能书写的话,就是在摄像头控件上面套一个InkCanvas了,这个写成一个自定义控件,命名为:CameraControl。

    <UserControl x:Class="MediaKit.CameraControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-MediaKit"
             xmlns:wpfmedia="clr-namespace:WPFMediaKit.DirectShow.Controls;assembly=WPFMediaKit"
             mc:Ignorable="d" 
             x:Name="window">
        <Canvas Height="{Binding Height, ElementName=window, Mode=OneWay}" Width="{Binding Width, ElementName=window, Mode=OneWay}"   HorizontalAlignment="Center">
            <InkCanvas Name="ink" Canvas.Left="0" Canvas.Top="0"  RenderTransformOrigin="0.5,0.5"  VerticalAlignment="Center" HorizontalAlignment="Center"  Height="{Binding ElementName=vce,Path=ActualHeight,Mode=OneWay}" Width="{Binding ElementName=vce,Path=ActualWidth,Mode=OneWay}">
                <InkCanvas.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </InkCanvas.RenderTransform>
            <wpfmedia:VideoCaptureElement  Height="1080"  x:Name="vce" Stretch="Fill"   RenderTransformOrigin="0.5,0.5"  >
                    
                </wpfmedia:VideoCaptureElement>
            </InkCanvas>
        </Canvas>
    

    2、拍照后能书写的话,就是在图片控件上面套一个InkCanvas了,这个也写成一个自定义控件,命名为:ImgControl。

      <UserControl x:Class="MediaKit.ImgControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MediaKit"
             mc:Ignorable="d" 
             x:Name="window">
    <Canvas Height="{Binding Height, ElementName=window, Mode=OneWay}" Width="{Binding Width, ElementName=window, Mode=OneWay}"   HorizontalAlignment="Center">
        <InkCanvas Name="ink" Canvas.Left="0" Canvas.Top="0"  RenderTransformOrigin="0.5,0.5"   VerticalAlignment="Center" HorizontalAlignment="Center"  Height="{Binding ElementName=img,Path=ActualHeight}" Width="{Binding ElementName=img,Path=ActualWidth}" >
            <InkCanvas.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform />
                    <TranslateTransform/>
                </TransformGroup>
            </InkCanvas.RenderTransform>
            <Image Name="img" VerticalAlignment="Center"  HorizontalAlignment="Center" Height="{Binding Height, ElementName=window, Mode=OneWay}"  Stretch="UniformToFill">
                
            </Image>
        </InkCanvas>
    </Canvas>
    

    3、需要切换摄像头和拍出来的照片,那我用一个list将用户控件丢进去,当然为了统一操作的话,我就写一个Class1类将CameraControl和ImgControl放进去。你需要有什么操作直接写在Class1里面就能通用了,比如移动,修改InkCanvas状态(书写,擦除等),放大缩小等等。

        #region ------构造函数------
        /// <summary>
        /// 添加摄像头页面
        /// </summary>
        public Class1()
        {
            pageIndex = 0;
            camera = new CameraControl();
            camera.ink.DefaultDrawingAttributes = PageManager.GetInstance()._defaultAttribuate;
            camera.ink.EditingMode = PageManager.GetInstance().editingMode;
            _inkCanvas = camera.ink;
            _vce = camera.vce;
            InitCameraThumb();//初始化幻灯片缩略图
            this.Children.Add(camera);
    
            _inkCanvas.IsManipulationEnabled = true;
            _inkCanvas.Focusable = true;
            _inkCanvas.PreviewMouseDown += _inkCanvas_PreviewMouseDown;
            (((TransformGroup)_inkCanvas.RenderTransform).Children[2] as RotateTransform).Angle = CommonMethod.s_angle;//初始化旋转
        }/// <summary>
        /// 添加图片页面
        /// </summary>
        /// <param name="source"></param>
        public Class1(ImageSource source, int index)
        {
            pageIndex = index;
            pic = new ImgControl(source);
            pic.ink.DefaultDrawingAttributes = PageManager.GetInstance()._defaultAttribuate;
            pic.ink.EditingMode = PageManager.GetInstance().editingMode;
            _inkCanvas = pic.ink;
            InitPageThumb();  //初始化幻灯片缩略图
            pageThumb.contentSource = source;
            this.Children.Add(pic);
    
            _inkCanvas.IsManipulationEnabled = true;
            _inkCanvas.Focusable = true;
            _inkCanvas.PreviewMouseDown += _inkCanvas_PreviewMouseDown;
            (((TransformGroup)_inkCanvas.RenderTransform).Children[2] as RotateTransform).Angle = CommonMethod.s_angle;//初始化旋转
        }
        #endregion ------构造函数------
    

    4、需要切换显示哪个的时候就在主界面的Grid里面操作

    Grid.Children.Clear();

    Grid.Children.Add(list[你要显示的页]);

    做到这里你以为就完成了么?然后你会发现切换到图片后,在切回去摄像头,摄像头是空白的,因为VideoCaptureElement 这个控件是不能被Remove再Add的,不然就需要重新加载,而且它本身加载就是比较慢的,有时候没释放完全还没发加载(VideoCaptureElement 控件只能加载一个空闲中的摄像头)

    解决方案目前有2个,一个就是换控件咯,就不用VideoCaptureElement 了嘛,用C#的AForge,虽然他是C#的控件,虽然AForge在wpf嵌进去比较丑(没有wpf的特性了:穿透),并且嵌进去步骤比较麻烦。

  • 相关阅读:
    命令提示符窗口adb shell 执行sqlite命令时进入 ...> 状态如何退出
    通过android studio 浏览模拟器中文件
    vim快捷键参考
    快速体验openstack-用devstack安装openstack
    css靠左,靠右
    全国-城市-百度地图中心点坐标
    java_dom4j解析xml
    December 31st, Week 53rd Tuesday, 2019
    December 28th, Week 52nd Saturday, 2019
    December 21st, Week 51st Saturday, 2019
  • 原文地址:https://www.cnblogs.com/caozhengze/p/15219115.html
Copyright © 2011-2022 走看看