Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 611|回复: 0

WPF中在摄像头视频上叠加控件的解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-10 16:52:20 | 显示全部楼层 |阅读模式

    一、视频呈现

      前段时间,在一个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号方案则可以用来兼容各大视频平台,例如有些视频平台不支持句柄的传入,则可以使用该方案。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 17:10 , Processed in 0.085439 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表