Qt6 qml 相机预览与处理

Qt6 qml 相机预览与处理

本文章适用于 qt6 的 quick程序,不适用于qt5!!

本文章在qt6.4.3版本下运行,windows及安卓都运行通过。

1. Main.qml

import QtQuick
import QtQuick.Window
import QtMultimedia

Window {
    width: 375
    height: 667
    visible: true
    title: qsTr("Hello World")
    objectName: "rootObject"

    // 屏幕适配, 以宽为基准方案
    function dp(pixel){
        if(Qt.platform.os === 'android'){
            return pixel / 375.0 * Screen.width
        }
        return pixel
    }

    Column {
        MediaDevices {
            id: mediaDevices
        }

        Item {
            id: itm
            // 0: android下是后置摄像头,1:前置摄像头
            // windows下很奇怪,所以我在videoOutput中用defaultVideoInput兜底
            property int cIndex: 0
            property int cWidth: (camera.cameraDevice.videoFormats[0]
                                  && camera.cameraDevice.videoFormats[0].resolution
                                  ? camera.cameraDevice.videoFormats[0].resolution.width
                                  : 1280)
            property int cHeight: (camera.cameraDevice.videoFormats[0]
                                   && camera.cameraDevice.videoFormats[0].resolution
                                   ? camera.cameraDevice.videoFormats[0].resolution.height
                                   : 768)


            width: dp(375)
            height: dp(375) / cWidth * cHeight

            // 声明视频输出组件
            VideoOutput {
                id: videoOutput
                objectName: "videoOutput"
                anchors.fill: parent
                fillMode: VideoOutput.Stretch
            }

            // 创建视频会话
            CaptureSession {
                // 创建并选择相机
                // android底层用的应该是camera2,部分root型号安卓机可以同时打开多个摄像头
                // 大部分只能打开1个摄像头
                // 不可能是cameraX,因为原生cameraX所有机型仅支持1个相机
                camera: Camera {
                    id: camera
                    cameraDevice: mediaDevices.videoInputs[itm.cIndex] || mediaDevices.defaultVideoInput
                    // TODO 加各种配置,如自动缩放,焦点等,官方文档有说明
                }
                // 与声明的视频输出组件作绑定
                videoOutput: videoOutput
                // 绑定完成启动相机
                onVideoOutputChanged: {
                    camera.start()
                }
            }
        }

        Text {
            // 相机视频流的宽高,很可能系统不给你
            text: `cWidth: ${itm.cWidth}, cHeight: ${itm.cHeight}`
            font.pixelSize: dp(21)
        }
    }
}

2. main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QVideoSink>
#include <QVideoFrame>
#include <QDebug>
#include "VideoHandler.hpp"


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;


    const QUrl url(u"qrc:/demo1/Main.qml"_qs);
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
        &app, []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);

    engine.load(url);

    // 视频流处理对象
    VideoHandler videoHandler;
    // 查找 qml VideoOutput
    int rootSize = engine.rootObjects().size();
    for(int i=0; i< rootSize; i++){
        auto item = engine.rootObjects().at(i);
        if(item->objectName() == "rootObject"){
            QObject * root = item;
            // 找到后,进行信号与槽连接
            auto videoOutput = root->findChild<QObject *>("videoOutput");
            // 官方文档说 videoOutput 有个属性叫 videoSink,它是个 QVideoSink 指针对象
            QObject * videoSink = qvariant_cast<QObject*>(videoOutput->property("videoSink"));
            // 打印分析是否获取到 QVideoSink 指针对象
            qDebug() << videoSink->objectName() << " " << videoSink << Qt::endl;
            QVideoSink * vsPtr = qobject_cast<QVideoSink *>(videoSink);
            // 官方文档还说,它有个信号,能获取到视频帧
            QObject::connect(vsPtr, &QVideoSink::videoFrameChanged, &videoHandler, &VideoHandler::videoFrameChanged);

            break;
        }
    }

    return app.exec();
}

3. VideoHandler.hpp

#ifndef VIDEOHANDLER_HPP
#define VIDEOHANDLER_HPP

#include <QObject>
#include <QVideoFrame>
#include <QDebug>

class VideoHandler: public QObject {

private :
    int num = 0;
public slots:
    // 进行逐帧视频流处理
    void videoFrameChanged(const QVideoFrame &frame) {
        // 首帧打印帧格式
        if(num == 0){
            qDebug() << "format: " << frame.pixelFormat() << Qt::endl;
            ++num;
        }
        // TODO 逐帧分析,如人脸识别
    }
};

#endif // VIDEOHANDLER_HPP
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt6 QML实时开发是基于Qt6平台的快速开发框架,它利用Qt Quick语言和QML技术,为开发人员提供了设计和开发图形用户界面(GUI)所需的各种工具。QML是一种描述用户界面的语言,借助它可以轻松地创建各种精美的用户界面。 Qt6 QML实时开发的主要优点是其实时性和高效性。它可以让开发人员在软件开发过程中实时预览结果,使开发效率大大提高。同时,Qt6 QML实时开发还支持快速迭代和动态调整,便于开发人员随时调整和修改界面,同时保证了UI的高度灵活性和可扩展性。 Qt6 QML实时开发还提供了丰富的控件和组件库,这些库都是经过优化和测试的,能够让开发人员快速构建和布局GUI和用户交互界面。此外,Qt6 QML实时开发还支持跨平台开发,可用于开发Android、iOS、Windows、macOS和Linux等平台的应用程序。 综上所述,Qt6 QML实时开发是一种快速、高效、灵活的开发框架,在图形用户界面开发中应用广泛,也是未来GUI开发的一个趋势。它不仅可以大大提高开发效率,同时还提供了丰富的控件和组件,支持跨平台开发,是一款非常有价值的开发工具。 ### 回答2: Qt6 QML是一个开发桌面和移动应用程序的框架,其实时开发方案也得到了广泛的支持和认可。Qt6 QML通过其强大的功能和易于使用的界面设计,使开发人员可以更加方便和快速地开发出高质量的应用程序。 在Qt6 QML实时开发中,其主要特点包括: 1. 设计驱动型开发 Qt6 QML采用的是设计驱动型开发,开发人员可以直接在设计界面中进行开发与调试,而不需要手动写代码。这种开发方式可以大大提高开发效率,同时也可以有效降低错误发生的概率。 2. 实时预览界面效果 Qt6 QML具有实时预览界面效果的功能,这意味着开发人员可以在编写代码的同时观察到其效果,从而快速定位和修复问题。这种实时预览的功能也能够提高开发效率,并且可以让开发过程更加享受。 3. 基于组件的开发 Qt6 QML支持基于组件的开发,可以通过在不同的组件之间进行组合,以构建更高级的组件和应用程序。这种基于组件的开发方式,可以大大提高代码的可重用性,减少代码的冗余度。 综上所述,Qt6 QML实时开发是一个高效、方便和灵活的开发工具,可以使开发人员更加轻松和快速地开发出高质量的应用程序。同时,其具有丰富的功能和易于使用的界面设计,也可以让开发过程更加有趣和愉悦。 ### 回答3: Qt6 QML实时开发,指的是使用Qt6和QML技术进行实时开发的过程。Qt6是一种跨平台的应用程序框架,它可以帮助开发者快速创建高性能、现代化的应用程序,而QML则是一种基于JavaScript的用户界面语言,可以帮助开发者快速构建交互式的用户界面。因此,Qt6 QML实时开发可用于开发实时交互应用程序,如数据可视化、游戏、嵌入式系统等领域。 在Qt6 QML实时开发中,开发者可以使用Qt Creator等集成开发环境(IDE)轻松创建QML应用程序。QML语言支持丰富的界面元素和动画效果,使得界面设计非常灵活。此外,Qt6提供了丰富的C++类库和工具,方便开发者实现高性能的后台逻辑和各种设备的接口。 Qt6 QML实时开发的优势在于快速迭代。开发者可以使用实时预览功能,即在编辑代码时即时看到修改后的效果,从而提高开发效率和设计灵活性。此外,由于Qt6和QML都为开发者提供了丰富的功能和现成的库文件,因此可以极大地减少开发时间和成本。 总之,Qt6 QML实时开发是一种高效的技术和方法,可用于实现高性能、现代化的应用程序,为开发者提供快速迭代和灵活性,是目前最流行的开发方式之一。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值