QML调用Android摄像头,并将每一帧传入C++进行处理(QML 对象,转化为C++对象)

第一步:搭建好Qt for Android 开发环境

搭建环境参考:Qt for Android 环境搭建

第二步,创建Qt工程

注意选择创建Qt Quick工程

.pro文件中加入模块:

QT += androidextras multimedia multimediawidgets

第三步:新添加一个C++类 CameraFromQML,继承于QObject

在这里插入图片描述

CameraFromQML.h

#ifndef CameraFromQML_H
#define CameraFromQML_H

#include <QObject>
#include <QVideoProbe>
#include <QVideoFrame>
#include <QVideoSurfaceFormat>
#include <QCamera>
#include <QDateTime>
#include <QThread>

class CameraFromQML : public QObject
{
    Q_OBJECT

    //Qt属性,与QML对象属性类似
    Q_PROPERTY( QObject* qmlCamera READ getQmlCamera WRITE setQmlCamera )

public:
    explicit CameraFromQML( QObject *parent = nullptr  );
	
	//获取类的属性, 返回_qmlCamera对象
    QObject *getQmlCamera() const;

	//设置类的属性qmlCamera, 传入QML对象Camera,然后将_qmlCamera设置为qmlCamera
    void setQmlCamera( QObject *qmlCamera );

private slots:
	
	//槽函数:与QVIdeoProbe的videoFrameProbe信号绑定,在这个槽函数可以对摄像头捕获到的每一帧进行自定义处理
    void _onProcssFram( const QVideoFrame &frame );
private:

	//从QML获取到的Camera对象
    QObject *_qmlCamera = nullptr;
    
    //在C++中的QCamera对象
    QCamera *_camera = nullptr;

	//QVideoProbe类,只能在Android设备上使用,当设备的摄像头有帧数据的时候,会发出videoFrameProbed信号
    QVideoProbe _probe;
	
	//调试时,计算获取每一帧的时间使用的变量
    qint64 lastTime = 0;
};

#endif // CameraFromQML_H

CameraFromQML.cpp

#include "CameraFromQML.h"

#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QtAndroid>
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#endif

#include <QDebug>

CameraFromQML::CameraFromQML( QObject *parent ) :
    _qmlCamera( nullptr ),
    _camera( nullptr )
{
    Q_UNUSED( parent )
}

QObject *CameraFromQML::getQmlCamera() const
{
    return _qmlCamera;
}

void CameraFromQML::setQmlCamera( QObject *qmlCamera )
{
    this->_qmlCamera = qmlCamera;
    if( _qmlCamera )
    {
    	//将QML对象转换为C++对象
        _camera = qvariant_cast< QCamera* >( _qmlCamera->property( "mediaObject" ) );
        
        //将类QVideoFrameProbe的实例化对象_probe的数据来源设为_camera
        if( _probe.setSource( _camera ) )
        {
         //	链接信号槽,每当_probe有新的一帧数据( frame )来时,使用信号槽将frame发送至槽函数_onProcssFrame 进行想要的处理。
             connect( &_probe, SIGNAL( videoFrameProbed( const QVideoFrame &frame ) ),
                      this, SLOT( _onProcssFram( const QVideoFrame &frame ) ) );
        }
    }
    qDebug() << "set Camera success!";
}

void CameraFromQML::_onProcssFram( const QVideoFrame &frame )
{
    //在此处进行想要对每一帧进行的处理
    qDebug() << "here comes the frame from camera";
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "CameraFromQML.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    
	//将C++类 CameraFromQML 注册进QML,可以作为单独的一个模块来使用
    qmlRegisterType< CameraFromQML >( "CameraFromQML", 1, 0, "CameraFromQML" );
    
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.4
import QtMultimedia 5.9
import CameraFromQML 1.0

ApplicationWindow {
    visible: true
    width:  Qt.platform.os === "android"? Screen.width: 640
    height:  Qt.platform.os === "android"? Screen.height: 480
    title: qsTr( "Android Camera" )

    //获取设备摄像头列表
    property var cameras: QtMultimedia.availableCameras

    Camera{
        id: camera

        // 捕获静态图像
        captureMode: Camera.CaptureStillImage

        // 后置摄像头
        deviceId: cameras[1].deviceId
        focus{
            // 焦点模式
            focusPointMode: Camera.FocusPointCenter

            // 连续自动对焦模式
            focusMode: Camera.FocusContinuous

        }

        imageProcessing{
            // 白平衡自动
            whiteBalanceMode:CameraImageProcessing.WhiteBalanceAuto
        }

        // 闪光灯自动
        flash.mode:Camera.FlashAuto

        imageCapture{
            resolution: Qt.size(1920,1080)
            onImageCaptured: {
                camera.stop()
            }
        }
    }

    //来自于C++类的模块
    CameraFromQML{
        id: fileter

        //此处会调用C++类 CameraFromQML中, 属性的setQmlCamera( QObject *qmlCamera ) 方法
        qmlCamera: camera
    }

    Rectangle{
        width: 480
        height: 480
        anchors.left: parent.left
        anchors.verticalCenter: parent.verticalCenter
        border.color: "red"
        rotation: 90

        //摄像机画面输出控件
        VideoOutput{
            id:viewfinder
            source: camera
            anchors.fill: parent
            fillMode: VideoOutput.PreserveAspectCrop
        }
    }
}

运行效果

tips:

1.软件上的画面是来自于qml代码中的控件VideoOutput
2.windows 和 linux 上捕获摄像头每一帧的方法与在Android设备上捕获的方法有所不同
在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值