Qt截取摄像头并显示截图效果详解

Qt截取摄像头并显示截图效果详解

使用qt和opencv制作一个人脸录入系统时,通过qt截取保存人脸后用户没有得到及时的反馈,既没有截图结束通知,也不知道截得怎么样,所以希望可以实现手机截图产生的那种动画效果。

这种截图效果是新产生了一个动画控件显示,然后消失,所以我们新创建一个截图效果类BlinkFrame,并在主窗口MainWindow中应用该类。

截图特效演示:

在这里插入图片描述

代码参考

先贴出截图特效代码:

头文件:

#include <QPropertyAnimation>
#include <QRect>
#include <QLabel>
#include <QPixmap>
#include <QTimer>
#include <QDesktopWidget>
#include <QApplication>


class BlinkFrame : public QWidget
{
	Q_OBJECT

public:
	explicit BlinkFrame(QWidget *parent = 0);
	~BlinkFrame();
	void setSnapshotPixmap(const QPixmap &pixmap);     //获取要截取的图片
	void show();                                 //显示动画
	void setInitRect(QRect rect);                //获取截图的位置大小信息
    
private:
	QLabel* mBGLabel;     //显示截取的图片
	QRect mRect;          //获取截图的位置大小信息
	QPixmap mFitpixmap;     //获取截取图片
	QPropertyAnimation* mShowAnimal;       //声明一个属性动画对象
};

源文件:

BlinkFrame::BlinkFrame(QWidget *parent) :
    QWidget(parent)
{
	setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	setAttribute(Qt::WA_TranslucentBackground, true);
        
	mBGLabel = new QLabel(this);
	mBGLabel->setStyleSheet("background-color:white");
	mShowAnimal = new QPropertyAnimation(mBGLabel, "geometry");
}


BlinkFrame::~BlinkFrame()
{

}


void BlinkFrame::setInitRect(QRect rect)
{
	mRect = rect;
}


void BlinkFrame::setSnapshotPixmap(const QPixmap &pixmap)
{
	mFitpixmap = pixmap;
}


void BlinkFrame::show()
{
    //设置动画的持续时间为400ms,在创建一个proertyAnimation对象时,默认的动画持续时间为250ms
	mShowAnimal->setDuration(400);
    //设置动画初始值,动画对象初始大小以及位置由mRect对象决定
	mShowAnimal->setStartValue(mRect);
    //设置动画结束值,动画结束时的坐标和大小由QRect对象决定,自行设定动画结束的位置
	mShowAnimal->setEndValue(QRect(mRect.x(), mRect.y() + mRect.height()*0.7, mRect.width()*0.3, mRect.height()*0.3));
       
	connect(mShowAnimal, &QPropertyAnimation::finished, this, [=](){
		mFitpixmap = mFitpixmap.scaled(mBGLabel->width(), mBGLabel->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
		mBGLabel->setPixmap(mFitpixmap);   //在label上显示截取的图像
		mBGLabel->setAlignment(Qt::AlignCenter);       //设置label上内容为居中对齐
		QTimer::singleShot(900, [=](){
			hide();
			this->deleteLater();
		});
	});
    
    //获取桌面控件
	QDesktopWidget* desktop = QApplication::desktop();
	int count = desktop->screenCount();            //返回系统可用桌面的数量
	int tempWidth = 0;
	int tempHeight = 0;
	
	if (count > 0)
    {
        //screenGeometry返回桌面坐标,count-1为桌面index,是从0开始的
        tempWidth += desktop->screenGeometry(count - 1).width();
        tempHeight = desktop->screenGeometry(count - 1).height();
    }
	
    //设置动画初始大小,坐标(0, 0)随意,因为初始坐标已经设定了
	this->setGeometry(0, 0, tempWidth, tempHeight);
    this->setVisible(true);         //显示动画控件
    
	mShowAnimal->start();          //开始动画
}

MainWindow中的应用:

BlinkFrame *blinkLabel = new BlinkFrame();
QRect m_previewRect(100, 0, 800, 800);
blinkLabel->setInitRect(m_previewRect);         //设置初始大小坐标
blinkLabel->setSnapshotPixmap(*current_img);     //传入要截图显示的图片
blinkLabel->show();            //显示动画

部分代码详解:

blinkframe.cpp

构造函数:

  1. void setWindowFlags(Qt::WindowFlags type) //设置截图窗口属性,即窗口类型type,还有属性标志WindowFlags也就是设置窗口的各种属性

    setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) //表示该窗口为子窗口,FramelessWindowHint 代表窗口无边框,WindowStaysOnTopHint设置该窗口总是在其它窗口的顶部

    详细可在qt creator参见Qt官方文档,或者参考

  2. void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on = true) //参数二为true则设置窗口控件属性,否则清空该属性

    setAttribute(Qt::WA_TranslucentBackground, true) //WA_TranslucentBackground可设置窗口控件透明,缺少此处时显示动画时主窗口消失

    setWindowFlags与setAttribute

  3. QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = Q_NULLPTR) //创建一个动画对象,作用对象为target

    mShowAnimal = new QPropertyAnimation(mBGLabel, "geometry") //使用QProertyAnimation属性动画库,绑定对象为一个label标签,属性名为"geometry"

show()函数:

  1. void setStartValue(const QVariant &value) //设置动画的初始值

    mShowAnimal->setStartValue(mRect) //动画对象初始大小以及位置由mRect对象决定

  2. void setEndValue(const QVariant &value) //同理为设置动画结束值

    mShowAnimal->setEndValue(QRect) //动画结束时的坐标和大小由QRect对象决定

  3. lambda介绍

    /*下述信号槽连接,发信号对象为QProertyAnimation动画,
      信号finished当动画被停止或者结束时被发送出
      接收对象为this
      槽函数使用的是lambda表达式
    */
    connect(mShowAnimal, &QPropertyAnimation::finished, this, [=](){
            mFitpixmap = mFitpixmap.scaled(mBGLabel->width(), mBGLabel->height(), 				Qt::IgnoreAspectRatio, Qt::FastTransformation);
            mBGLabel->setPixmap(mFitpixmap);
            mBGLabel->setAlignment(Qt::AlignCenter);
            QTimer::singleShot(900, [=](){
                hide();
                this->deleteLater();
            });
        });
        
        
    
    1. QPixmap.scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation) //返回用所给的w和h框出来的矩形QPixmap
    2. void QTimer::singleShot(int msec, Functor functor) //在经过msec时间后自动调用函数,函数以指针传入
    3. hide() //默认隐藏了动画,和this->hide()是一样的
    4. this->deleteLater() //在对象进入时间循环后删除对象,释放内存

    MainWindow.cpp

    截取摄像头人脸保存代码:

    void MainWindow::save_image()
    {
        //获取摄像头当前显示的帧
        const QPixmap *current_img = ui->camera_label->pixmap();
        QString id = ui->id_line_edit->text();         //获取界面输入的人名id
        QString dir = face_dir;
        dir = dir + id + ".jpg";       //id名就是保存的图片名
        //string s = dir.toStdString();
        //cout << s << endl;
        current_img->save(dir);           //将当前图片保存在指定路径dir中
    
        //开始显示截图动画特效
        BlinkFrame *blinkLabel = new BlinkFrame();
        QRect m_previewRect(100, 50, 800, 800);
        blinkLabel->setInitRect(m_previewRect);
        //const QPixmap pp = QPixmap::fromImage(img);
        blinkLabel->setSnapshotPixmap(*current_img);
        blinkLabel->show();
    }
    

截图对象BlinkFrame 的内存定义最好使用时再定义,若在构造函数中定义在使用一次后就会被this->deleteLater()函数回收内存,就无法再使用。

关于label上图片的保存方法参考

暂记到此,如有错误,敬请批正。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Qt 框架可以使用 Qt Multimedia 模块读取摄像头数据并显示。下面是一个简单的例子: 1. 创建一个 Qt Widgets 项目 2. 在窗口上放置一个 QCameraViewfinder 3. 创建一个 QCamera 对象,并将其与 QCameraViewfinder 关联 4. 调用 QCamera::start() 开始预览摄像头数据 5. 调用 QCamera::stop() 停止预览 具体的代码实现可以参考 Qt 官方文档:https://doc.qt.io/qt-5/qtmultimedia-multimediawidgets-camera-example.html ### 回答2: Qt是一个跨平台的C++开发框架,提供了丰富的图形界面和多媒体功能。要实现在Qt中读取摄像头数据并显示,需要使用Qt的多媒体模块和图形界面模块。 首先,在Qt项目中包含多媒体和图形界面模块的头文件,如QCamera、QCameraViewfinder和QVBoxLayout。然后创建一个Qt窗口或者对话框,在这个窗口中添加一个布局管理器。 接着,创建一个QCamera对象,通过QCamera的静态函数availableDevices()获取可用的摄像头列表,并且选择一个要打开的摄像头。通常,它可以是电脑上的内置摄像头或者外置摄像头。 然后,创建一个QCameraViewfinder对象用于实时预览摄像头捕捉的图像。将QCameraViewfinder对象添加到之前创建的布局管理器中,这样它就被放置在窗口中的适当位置。 接下来,将QCamera的视图设置为QCameraViewfinder,通过调用QCamera的setViewfinder()函数,将QCameraViewfinder对象作为参数传入。 最后,通过调用QCamera的start()函数启动摄像头捕捉图像的功能。在Qt的事件循环中,摄像头会以固定的帧率不断地产生图像,并且QCameraViewfinder会实时显示这些图像。 对于一些高级功能,如调整摄像头的分辨率、帧率、对焦等,可以通过QCamera的其他函数和信号槽来操作。 完成了上述步骤后,编译并运行程序,就可以在Qt窗口中看到摄像头捕捉的实时图像了。 总结起来,实现Qt读取摄像头数据并显示的步骤如下:创建一个Qt窗口,添加布局管理器;创建并选择一个QCamera对象;创建一个QCameraViewfinder对象,将它添加到布局管理器中;将QCamera的视图设置为QCameraViewfinder;启动摄像头捕捉图像的功能。 ### 回答3: 使用Qt读取摄像头数据并显示需要以下步骤: 1. 首先,需要在Qt项目中包含Multimedia模块。可以在项目文件(.pro)中添加`QT += multimedia`。 2. 创建一个Qt窗口界面来显示摄像头数据。可以使用Qt的界面设计器创建一个QWidget窗口,并在窗口中添加一个标签(QLabel)来显示摄像头数据。 3. 在代码中,使用QCamera类来访问和控制摄像头设备。可以创建一个QCamera对象,并设置一些参数,例如摄像头源和分辨率等。然后,通过调用QCamera的start()函数来开始摄像头捕捉。 4. 使用QCameraViewfinder类将摄像头数据显示在窗口上。可以创建一个QCameraViewfinder对象,并设置它作为QCamera的视图(QCamera::setViewfinder())。然后,将QCameraViewfinder对象的窗口部件(QCameraViewfinderWidget)添加到窗口中,以便在界面上显示摄像头图像。 5. 最后,调用`show()`函数显示窗口,并应用Qt事件循环(QApplication::exec())来接收摄像头数据并更新显示。 下面是一个示例代码: ```cpp #include <QtWidgets> #include <QtMultimedia> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建Qt窗口界面 QWidget window; QLabel label(&window); // 创建QCamera对象 QCamera camera; // 设置摄像头参数 QCameraViewfinderSettings settings; settings.setResolution(640, 480); camera.setCaptureMode(QCamera::CaptureStillImage); camera.setViewfinder(&label); camera.start(); // 显示窗口 window.show(); // 运行Qt事件循环 return app.exec(); } ``` 这段代码创建了一个新的Qt应用程序,创建了一个窗口和一个标签来显示摄像头数据。使用QCameraViewfinderSettings设置了摄像头的分辨率,并将摄像头视图设置为标签。在最后调用`app.exec()`运行了Qt事件循环,用于接收摄像头数据并更新窗口显示
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值