使用视频当背景2.0

上次说了《使用视频当背景1.0》,有的人必须使用视频当背景,但是上次的代码风险又颇多,那到底有没有办法解决呢?其实是有的,比较麻烦而已,话不多说,上代码:

最终画面代码
loginwidget.h

#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H

#include <QWidget>
#include <QLabel>
#include <QResizeEvent>
#include "inforwindow.h"
#include "videowidget.h"

class LoginWidget : public QWidget
{
    Q_OBJECT
public:
    LoginWidget(QWidget *parent = 0);
    ~LoginWidget();
private:
    VideoWidget     *m_pVideoWidget = nullptr;          //背景
    InforWindow     *m_pInforWindow = nullptr;          //登录窗口
};

#endif // LOGINWIDGET_H

loginwidget.cpp

#include <QMovie>
#include "loginwidget.h"

LoginWidget::LoginWidget(QWidget *parent)
    : QWidget(parent)
{
    setMinimumSize(1000,800);

    /*窗口背景*/
    m_pVideoWidget = new VideoWidget(this);

    /*登录窗口*/
    m_pInforWindow = new InforWindow(m_pVideoWidget);
    m_pInforWindow->setAttribute(Qt::WA_TranslucentBackground,true);  //背景透明
    m_pInforWindow->setWindowFlags(Qt::FramelessWindowHint
                                   |Qt::WindowStaysOnTopHint);//无边框,置顶
    m_pInforWindow->setGeometry(477,466,949,186);
}

LoginWidget::~LoginWidget()
{
    delete m_pVideoWidget;
    delete m_pInforWindow;
}

视频播放代码
videowidget.h

#ifndef VIDEOWIDGET_H
#define VIDEOWIDGET_H

#include <QMainWindow>
#include <QWidget>
#include <QPaintEvent>
#include <QImage>
#include <QTimer>
#include <cv.h>
#include <highgui.h>
#include <opencv2/opencv.hpp>
#include "inforwindow.h"

class VideoWidget : public QWidget
{
    Q_OBJECT
public:
    VideoWidget(QWidget *parent = 0);
    ~VideoWidget();

protected:
   void paintEvent(QPaintEvent *e);

private slots:
   void slot_nextFrame();

private:
   InforWindow  *m_pInforWindow = nullptr;  //密码输入框
   CvCapture    *m_pCapture = nullptr;
   IplImage     *m_pIplImage = nullptr;
   IplImage     *m_pFrame = nullptr;
   QImage       *m_pImage = nullptr;
   QTimer       *m_pTimer = nullptr;
};

#endif // VIDEOWIDGET_H

videowidget.cpp

#include "videowidget.h"
#include <QPainter>
#include <QDebug>

VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent)
{
    m_pCapture = cvCaptureFromFile("../VideoWidget/test.mp4");
    if (m_pCapture)
    {
        m_pFrame = cvQueryFrame(m_pCapture);
        if (m_pFrame)
        {
            this->resize(m_pFrame->width,m_pFrame->height);
        }
        m_pImage = new QImage(QSize(m_pFrame->width,m_pFrame->height),
                              QImage::Format_RGB888);
        m_pIplImage = cvCreateImageHeader(cvSize(m_pFrame->width,m_pFrame->height),8,3);
        m_pIplImage->imageData = (char*)m_pImage->bits();
        m_pTimer = new QTimer(this);
        m_pTimer->setInterval(18);
        connect(m_pTimer,SIGNAL(timeout()),this,SLOT(slot_nextFrame()));
        m_pTimer->start();
    }
}

VideoWidget::~VideoWidget()
{
    cvReleaseImage(&m_pIplImage);
    cvReleaseCapture(&m_pCapture);
    delete m_pInforWindow;
    delete m_pFrame;
    delete m_pImage;
    delete m_pTimer;
}

void VideoWidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    painter.drawImage(QPoint(0,0),*m_pImage);
}

void VideoWidget::slot_nextFrame()
{
    m_pFrame = cvQueryFrame(m_pCapture);
    if(m_pFrame)
    {
        if(m_pFrame->origin == IPL_ORIGIN_TL)
        {
            cvCopy(m_pFrame,m_pIplImage,0);
        }
        else
        {
            cvFlip(m_pFrame,m_pIplImage,0);
        }
        cvCvtColor(m_pIplImage,m_pIplImage,CV_BGR2RGB);
        this->update();
    }
    else
    {
        /*设置循环播放*/
        cvReleaseImage(&m_pIplImage);
        cvReleaseCapture(&m_pCapture);
        delete m_pImage;
        m_pCapture = cvCaptureFromFile("../VideoWidget/test.mp4");
        if (m_pCapture)
        {
            m_pFrame = cvQueryFrame(m_pCapture);
            if (m_pFrame)
            {
                this->resize(m_pFrame->width,m_pFrame->height);
            }
            m_pImage = new QImage(QSize(m_pFrame->width,m_pFrame->height), QImage::Format_RGB888);
            m_pIplImage = cvCreateImageHeader(cvSize(m_pFrame->width,m_pFrame->height), 8,3);
            m_pIplImage->imageData = (char*)m_pImage->bits();
            m_pTimer->start();
        }
    }
}

登录界面代码
inforwindow.h

#ifndef INFORWINDOW_H
#define INFORWINDOW_H

#include <QWidget>
#include <QLineEdit>
#include <QLabel>
#include <QObject>
#include <QPushButton>

class InforWindow : public QWidget
{
    Q_OBJECT
public:
    InforWindow(QWidget *parent = 0);
    ~InforWindow();

private:
    QLabel          *m_pPasswordLabel = nullptr;    //提示输入密码
    QLabel          *m_pInformationLabel = nullptr; //提示按回车

    QLineEdit       *m_pPasswordLineEdit = nullptr; //密码输入框

    QPushButton     *m_pIsVisibleBtn = nullptr;     //设置密码是否可见按键
    QPushButton     *m_pConfirmBtn = nullptr;       //确认按键

    bool            m_isVisible = false;            //判断按钮状态标志

private slots:
    void            slot_isVisibleBtnClicked();     //是否可见按键响应函数
    void            slot_isConfirmBtnClicked();     //确认按键响应函数
};

#endif // INFORWINDOW_H

inforwindow.cpp

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFile>
#include <QDebug>
#include "inforwindow.h"

InforWindow::InforWindow(QWidget *parent)
    : QWidget(parent)
{
    QFile qssfile(":/style.qss");
    qssfile.open(QFile::ReadOnly);
    QString qss;
    qss = qssfile.readAll();
    this->setStyleSheet(qss);

    m_pPasswordLabel = new QLabel(this);
    QPixmap passwordPixmap(":/password.png");
    m_pPasswordLabel->setPixmap(passwordPixmap);

    m_pInformationLabel = new QLabel(this);
    QPixmap pressEnterPixmap(":/pressenter.png");
    m_pInformationLabel->setPixmap(pressEnterPixmap);

    m_pPasswordLineEdit = new QLineEdit(this);
    m_pPasswordLineEdit->setEchoMode(QLineEdit::Password);
    connect(m_pPasswordLineEdit, SIGNAL(returnPressed()),
            this,SLOT(slot_isConfirmBtnClicked()));

    m_pIsVisibleBtn = new QPushButton(this);
    if(!m_isVisible)
    {
        m_pIsVisibleBtn->setObjectName(tr("VisibleBtn"));
    }
    else
    {
        m_pIsVisibleBtn->setObjectName(tr("InVisibleBtn"));
    }
    m_pIsVisibleBtn->move(((this->width()*9.4)/1.3),(this->height()*5));
    connect(m_pIsVisibleBtn,SIGNAL(clicked(bool)),
            this,SLOT(slot_isVisibleBtnClicked()));

    m_pConfirmBtn = new QPushButton(this);
    m_pConfirmBtn->setObjectName(tr("ComfirmBtn"));
    m_pConfirmBtn->move(((this->width()*9.4)/1.1),(this->height()*5));

    connect(m_pConfirmBtn,SIGNAL(clicked(bool)),
            this,SLOT(slot_isConfirmBtnClicked()));

    m_pPasswordLabel->setGeometry(0,0,267,16);
    m_pPasswordLineEdit->setGeometry(0,48,944,72);
    m_pIsVisibleBtn->setGeometry(823,79,30,16);
    m_pConfirmBtn->setGeometry(895,67,44,34);
    m_pInformationLabel->setGeometry(828,142,113,15);
}

InforWindow::~InforWindow()
{
    delete m_pPasswordLabel;
    delete m_pInformationLabel;
    delete m_pPasswordLineEdit;
    delete m_pIsVisibleBtn;
    delete m_pConfirmBtn;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "loginwidget.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent=0);
    ~MainWindow();

private:
    LoginWidget* m_pLoginWidget = nullptr;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    m_pLoginWidget = new LoginWidget;
    m_pLoginWidget->show();
}

MainWindow::~MainWindow()
{
    delete m_pLoginWidget;
}

qss内容

*{
    background:transparent;
    color: white
}

QLineEdit{
    border-style: solid;
    border-left-width: 0px;
    border-right-width: 0px;
    border-top-width: 0px;
    border-bottom-width: 1px;
    border-bottom-color: white;
    font-family:"Microsoft YaHei";
    font-size: 48px
}

QPushButton#VisibleBtn{
    border-image: url(:/visible.png)
}

QPushButton#InVisibleBtn{
    border-image: url(:/invisible.png)
}

QPushButton#ComfirmBtn{
    border-image: url(:/confirm.png)
}

说明一下,因为QT QMediaPlayer机制的原因,所以底层播放不能使用QT QVideoWidget,于是这里使用了OpenCV,但是需要提前配置环境,比较麻烦,但是这个最为完美,不怕麻烦的可以尝试。

附上各种传送门:
使用动态图当背景图片:http://blog.csdn.net/fan_xingwang/article/details/79170087
使用视频当背景1.0:http://blog.csdn.net/fan_xingwang/article/details/79170463

最后,配置OpenCV环境,以下两个链接,请相互参考使用:
http://blog.csdn.net/zhaocj/article/details/38944037
http://blog.csdn.net/fang_chuan/article/details/52900834

猜你喜欢

转载自blog.csdn.net/fan_xingwang/article/details/79170673