zoukankan      html  css  js  c++  java
  • Qt

    1.     背景介绍

      中控端运行的操作系统是Android,中控软件主要功能有导航、收音机、媒体(音乐)、蓝牙(连接)、手机互联、行车辅助和系统设置等。

      仪表端运行的操作系统是Linux,仪表软件主要功能是将汽车CAN总线数据中有关车速、油量/电量、挡位和里程等信息解析处理并显示到汽车仪表盘上。

      新需求要将中控端导航、媒体(音乐)和蓝牙(连接)的画面投射到仪表端指定区域,并让驾驶员通过方向盘上的按钮来控制两端画面的同步切换。

      在使用开源多媒体框架Gstreamer实现了将中控端投射画面显示到仪表端之后,发现投射的画面出现不同大小的黑色区域(如下图1-1),并且黑色区域没有任何有用内容,为了满足软件开发需求,需要去掉黑色区域。

    图1-1

     2.     解决思路

    Gstreamer实现过程:配置Gstreamer参数到系统的环境变量中,通过Gstreamer的管道将投射接口与QML中显示媒体接口VideoOutput连接起来,就可以实现将中控端投射内容显示到仪表端了。

    1. export QT_GSTREAMER_CAMERABIN_VIDEOSRC=imxv4l2src  
    2. export QT_GSTREAMER_CAMERABIN_VIDEOSRC_DEVICE="/dev/video0" 

    以下是解决实现投屏之后遇到的显示画面中出现的黑色区域问题。

    2.1.    让投屏画面显示到QML组件上,再调整组件大小

      主要思想:通过调整加载投屏画面组件sceneLoader的宽高值,使其小于投屏画面本身的宽高值,从而达到显示面积等于有实际内容的投屏画面面积。

    1. //投屏显示  
    2. Loader{  
    3.     id: sceneLoader  
    4.     x: 1380  
    5.     y: 230  
    6.      500  
    7.     height: 100  
    8.     scale: 0.7  
    9.     sourceComponent :undefined  
    10.     ... ...  
    11.  }  

      结果:失败,投屏画面里面黑色区域随整体画面大小变化而等比例变化。

      其他类似方式,如调整组件sceneLoader所加载资源文件的宽高值;调整投屏画面的缩放值等,都未能解决问题。

    2.2.    将每帧投屏画面处理之后,再显示到QML组件上

      主要思想:把接收到的每帧投屏画面在C++代码端进行裁剪处理,再将处理后的每帧画面显示到QML组件上。

      结果:由于裁剪和刷新的效率低,导致画面会出现严重的延迟,最终失败。

    2.3.    使用OpacityMask遮罩将画面黑色区域遮住

      主要思想:使用Item元素的OpacityMask属性,将MaskSource画面遮罩在原Source上,最终得到一个以MaskSource形状显示出的部分Source内容的画面。

    官方示例如下:

    图2.3-1

    QML代码:

    1. import QtQuick 2.12  
    2. import QtGraphicalEffects 1.12  
    3.   
    4. Item {  
    5.      300  
    6.     height: 300  
    7.   
    8.     Image {  
    9.         id: bug  
    10.         source: "images/bug.jpg"  
    11.         sourceSize: Qt.size(parent.width, parent.height)  
    12.        smooth: true  
    13.        visible: false  
    14.    }  
    15.   
    16.    Image {  
    17.        id: mask  
    18.        source: "images/butterfly.png"  
    19.        sourceSize: Qt.size(parent.width, parent.height)  
    20.        smooth: true  
    21.        visible: false  
    22.    }  
    23.   
    24.    OpacityMask {  
    25.        anchors.fill: bug  
    26.        source: bug  
    27.        maskSource: mask  
    28.    }  
    29. }  

      思考:看到官方展示的效果之后,我们可不可以用一张和投屏画面(相当于图2.3-1中Source)相同尺寸的MaskSource图片,且将需要去掉的黑色面积部分制作为透明部分。

           结果:尝试发现该方法是可行的,下面将用一节来详细介绍解决过程。

     3.     使用OpacityMask属性

      按照2.3中的思路,通过和UI工程师沟通之后我们得到下图3-1作为MaskSource,同时将需要处理的图1-1作为Source。

    图3-1

    部分关键代码如下:

    1. VideoOutput{  
    2.         id: videoOutput  
    3.         source: camera  
    4.         visible: false  
    5.   
    6.         Camera{  
    7.             id: camera  
    8.         }  
    9.     }  
    10.    Image{  
    11.        id:mask  
    12.        source: "qrc:/images/mask_picture.png"  
    13.        visible: false  
    14.    }  
    15.  
    16.    OpacityMask{  
    17.        id: om  
    18.         1280  
    19.        height: 720  
    20.        source: videoOutput  
    21.        maskSource: mask  
    22.    }  

    最终运行效果如下图3-2:

    图3-2

      显示出来的效果像似黑色区域被裁剪掉了一样,如果要对上图3-2画面再做大小上面的调整,就只需要对di为om的对象进行长宽和大小上的缩放即可。

           运行过程中可以通过信号触发来更换maskSource,进一步来改变使用遮罩属性后的最终形状。

    遗留两处需补图的地方:

     

    博客园文作者:Citrusliu 博文地址:https://www.cnblogs.com/citrus
  • 相关阅读:
    3.8快乐
    只剩一个人了
    需求分析
    再也不看皇马比赛
    最近蛮忙,没头绪
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第5章 CSS3:选择器、字体和颜色模式
    ↗☻【高性能网站建设进阶指南 #BOOK#】第12章 尽早刷新文档的输出
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第4章 响应设计中的HTML5
    ↗☻【JavaScript】code
    ↗☻【高性能网站建设进阶指南 #BOOK#】第11章 划分主域
  • 原文地址:https://www.cnblogs.com/citrus/p/11803482.html
Copyright © 2011-2022 走看看