一、视频呈现

  前段时间,在一个wpf的项目中需要实时显示ip摄像头,对此的解决方案想必大家都应该知道很多。在winform中,我们可以将一个控件(一般用panel或者pictruebox)的句柄丢给摄像头的sdk以实现该功能,而在wpf中我们同样可以使用该方案快速实现。

  我们以海康平台为例,海康的sdk就需要我们传递一个控件的句柄,winform中可以直接使用控件的handle属性来获取句柄,而在wpf中我们则有两种方法:

  1、将WindowsFormsHost作为容器在内部嵌套一个winform控件,比如panel,这样的话就和winform中一样了;

  2、直接使用    ((HwndSource)PresentationSource.FromVisual(你的wpf元素)).Handle;  获取句柄;


二、叠加控件

  简单的视频展示使用一中的方案就可以解决,但我接手的项目是一个将摄像头视频用以AR处理的程序,界面上需要展示很多图标和信息栏,最重要的是整个主程序的大背景就是实时的摄像头画面,除此之外还有各种子窗口,子窗口中也要用到视频,这样就必然涉及到在视频画面上叠加控件的难题。  

  1、使用Microsoft.DwayneNeed

  之所以说是难题,是微软也在试图解决却也没有给出真正完美的解决方案。这个难题就是著名的空域问题(airspace issues)。这里有一份园友的随笔链接,主要介绍的是微软目前的解决方案:http://www.cnblogs.com/sela/p/4948102.html,这套方案在我实际使用中虽然可以正常的在视频上叠加控件,但在上方拖动控件则非常卡顿,通常的情况就是鼠标已经移动到了右侧,被拖控件还在左侧依依不舍,即便是release版本也无济于事,这套方案最终流产。 

  

  2、将视频流转码,使用d3d渲染为ImageSource

  此方案比较麻烦,需要自己控制转码过程,这里有一篇关于此方案的文章链接:http://blog.csdn.net/yangyy9611/article/details/17464133,我这里准备了一份demo(非本人编写):https://pan.baidu.com/s/1eSABfma,以下是demo运行的截图:

  大致的原理就是利用sdk的回调机制逐帧获取码流,再使用direct进行渲染;

  此方案除了代码量相对多点之外还存在和1中同样的问题,控件拖动时依然卡顿,各位园友不知有何好的解决办法呢。

  3、最终的解决方案

  在1和2都达不到理想中的要求时,我突然意识到一个问题,为什么会出现空域问题?那是因为winform和wpf的渲染方式不同,如果将他们统一,问题是不是解决了?只能说解决了一半,如果需要叠加的控件是规规矩矩的矩形,换句话说,不需要透明通道的那些控件,则完全可以使用这套方案,但是像那些有圆角的控件还需要另外想办法,我们先说前者吧,简单的代码如下:

<wfi:WindowsFormsHost>
<wf:Panel/>
</wfi:WindowsFormsHost>
<wfi:WindowsFormsHost Width="114" Height="152">
  <ElementHost>
    <Border Width="114" Height="152"/>
  </ElementHost>
</wfi:WindowsFormsHost>

  其实就是在 WindowsFormsHost再套一个ElementHost,现在无论是视频的panel还是在其上方的border控件由于都被WindowsFormsHost所包含,所以border在渲染时不会被覆盖到底层了。

  下面再谈谈我个人认为最难的不规则控件的叠加方式,如果你能在wpf应用中通过代码让WindowsFormsHost背景透明,那么你不需要再继续往下看了,请你联系我,我认为这才是最好的解决方案,而接下来我要说的方案可能会让你们不屑,甚至嘲笑。

  我的办法很简单,就是使用两个窗口,底部窗口单独显示视频,并设置为主窗口,顶部窗口设置AllowsTransparency="True",ShowInTaskbar="False",在显示顶部窗口时使用showdialog而不是show,这样能够保证用户永远在顶部窗口上操作,到不了视频窗口。针对子窗口的情况,虽然可以用popup来模拟上述过程,但popup也有很多问题,他默认是置顶的,有时会给用户带来困惑,比如两个子窗口重叠时,明明带视频的那个窗口在底部,但由于其中的视频部分使用的是popup来展示的,它居然会显示在顶层窗口之上,完美实现了窗口洗牌的特效,除此之外你还需要通过特殊的偏移量才能控制popup的位置,鉴于此,我建议你单独定制一个专门用来弹出信息的窗体,再将包含视频的控件作为子元素传入其中。

  最终的解决方案是结合这三种,由于主界面是个实时视频大背景,所以任何拖动的操作都不该延迟,所以主界面用了3号解决方案,而一些子界面不涉及到在上方拖动的操作,则可以用1号方案,至于2号方案则可以用来兼容各大视频平台,例如有些视频平台不支持句柄的传入,则可以使用该方案。

WPF中在摄像头视频上叠加控件的解决方案的更多相关文章

  1. WPF中。。DataGrid 实现时间控件和下拉框控件

    DatePicker 和新的 DataGrid 行 用户与 DataGrid 中日期列的交互给我造成了很大的麻烦. 我通过将一个 Data Source 对象拖动到 WPF 窗口上,创建了一个 Dat ...

  2. ASP.NET中的FileUpload文件上传控件的使用

    本篇文章教大家如何将客户端的图片或者文件上传到服务器: 无论是上传图片(.jpg .png .gif等等) 文档(word excel ppt 等等). 第一步:放入以下三个控件 Image控件,Fi ...

  3. 问题-Delphi在多线程中使用其他窗体上的控件,报“尚未调用CoInitialize”解决方法

    1.uses ActiveX; 2. procedure HLCJ.Execute;begin    CoInitialize(nil);    //要使用的控件    CoUninitialize; ...

  4. WPF中查找指定类型的父控件

    /// <summary> /// 查找父控件 /// </summary> /// <typeparam name="T"></type ...

  5. 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)

    前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...

  6. WPF自定义控件(二)の重写原生控件样式模板

    话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...

  7. 百度Ueditor多图片上传控件

    发现百度的Ueditor富文本编辑器中的多图片上传控件很不错,于是便想着分享出来使用,费了老劲,少不了无名朋友的帮助,也查了不少资料,终于搞定了 发代码给大家,请大家多多指正 1.首先要在html页面 ...

  8. 用MVVM模式开发中遇到的零散问题总结(4)——自制摄像头拍摄大头贴控件

    原文:用MVVM模式开发中遇到的零散问题总结(4)--自制摄像头拍摄大头贴控件 一直有个疑问,为什么silverlight对摄像头支持这么好,WPF却一个库都没有....于是我各种苦恼啊,各种Code ...

  9. asp.net中遍历界面上所有控件进行属性设置

    * 使用方法: *  前台页面调用方法,重置:    protected void Reset_Click(object sender, EventArgs e)        {           ...

随机推荐

  1. selenium 看有啥api 的文件(文件用编辑器 or 浏览器打开就可以看到有什么 api)

  2. MVC 公共类App_Code不识别

    .Net MVC需要写公共类的时候 右击添加 App_Code 文件夹,新建类—>右击类—>属性,生成操作 —>选择 —>编译 .net MVC项目本身是个应用程序,所以其实不 ...

  3. Linux - apache 服务

    暂时关闭 iptables 防火墙 [root@sch01ar ~]# systemctl stop iptables.service 暂时关闭 firewall 防火墙 [root@sch01ar ...

  4. ndarray的创建与数据类型

    ndarray 多维数组(N Dimension Array) NumPy数组是一个多维的数组对象(矩阵),称为ndarray,具有矢量算术运算能力和复杂的广播能力,并具有执行速度快和节省空间的特点. ...

  5. Vue 简单的总结三

    一.安装脚手架 1.下载node.js,本文下载版本为node-v8.12.0-x64.msi,一键式安装. 2.安装按成后,打开终端,输入node,可进入node环境(两次ctrl+c退出),如下图 ...

  6. EasyUI应用总结

    1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncod ...

  7. @Value关于static字段的注入

    @Component public class BaseCode { //应用key public static String APP_KEY; //应用密钥 public static String ...

  8. 19-EasyNetQ:用EasyNetQ.Hosepipe重新提交错误信息

    EasyNetQ.Hosepipe是EasyNetQ队列管理工具.用来取回队列中的消息并重新发布这些消息.还可以用它来检测错误队列,并重试发布消息. 用法 EasyNetQ.Hosepipe.exe ...

  9. 迷你MVVM框架 avalonjs 0.99发布

    在本版本主要是性能优化,添加一些有用的功能(如回调什么的),离成品阶段不远了. 修正 updateViewModel bug 修正监控数组的set方法 bug 添加data-each-rendered ...

  10. laravel中的数据库操作(增删改查)方法一

    导入命名空间和DBnamespace App\Http\Controllers; use Illuminate\Support\Facades\DB; public function index(){ ...