第一步:搭建好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设备上捕获的方法有所不同