LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

camera:一个基于QT+Weston的Camera应用

基于QT UI框架编写camera,作为Wayland Client运行。

QT Multimedia自带的camera示例程序位于examples/multimediawidgets/camera。

Camera Example | Qt Multimedia 5.15.16

1 camera框架

2 camera的mk文件

camera.mk配置:
TEMPLATE = app
TARGET = camera

QT += multimedia multimediawidgets--依赖的QT模块。

HEADERS = \--依赖的头文件,需要经过moc编译。
    camera.h \
    imagesettings.h \
    videosettings.h

SOURCES = \
    main.cpp \
    camera.cpp \
    imagesettings.cpp \
    videosettings.cpp

FORMS += \--
    camera.ui \
    videosettings.ui \
    imagesettings.ui

RESOURCES += camera.qrc

target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/camera
INSTALLS += target

QT+=widgets
include(../../multimedia/shared/shared.pri)

执行如下命令生成Makefile:

output/rockchip_rk3588/host/bin/qmake -o Makefile camera.pro -spec devices/linux-buildroot-g++ QMAKE_CXXFLAGS+=-DENABLE_WAYLAND_PLATFORM QMAKE_LFLAGS+=-lwayland-client

qmake-package是通过qmake统一处理生成Makefile,参考《Infrastructure for QMake-based packages》。qmake-package的实现位于package/pkg-qmake.mk

3 camera代码

moc(Meta Object Compiler)元对象编译器:把QT扩展的C++语法编译成标准C++代码。

rcc(Resource Compiler):把.qrc(QML的UI资源和图片等)文件编译成标准C++代码。

uic(UI Compiler):把.ui文件编译成标准C++代码。

QT代码的生成、编译过程如下:

以camera为例:

examples/multimediawidgets/camera/
├── camera--可执行文件。
├── camera.cpp--Camera类的实现。
├── camera.h--Camera类的定义。
├── camera.pro--camera工程配置文件,参考《Qt开发中如何正确的编写.pro文件及详细说明》。
├── camera.qrc--camera资源文件。
├── camera.ui--camera应用UI配置文件。经过uic编译生成。
├── doc
│   ├── images
│   │   └── camera-example.png
│   └── src
│       └── camera.qdoc
├── images
│   └── shutter.svg
├── imagesettings.cpp--ImageSettings类的实现。
├── imagesettings.h--ImageSettings类的定义。
├── imagesettings.ui--拍照窗口UI配置文件。
├── main.cpp--camera程序主入口。
├── Makefile--根据camera.pro生成的Makefile。
├── .moc
│   ├── moc_camera.cpp--moc编译带关键字Q_OBJECT的camera.h得到moc_camera.cpp。
│   ├── moc_imagesettings.cpp--moc编译带关键字Q_OBJECT的imagesettings.h得到moc_imagesettings.cpp。
│   ├── moc_predefs.h--预定义的宏。
│   └── moc_videosettings.cpp--moc编译带关键字Q_OBJECT的videosettings.h得到moc_videosettings.cpp。
├── .obj
│   ├── camera.o
│   ├── imagesettings.o
│   ├── main.o
│   ├── moc_camera.o
│   ├── moc_imagesettings.o
│   ├── moc_videosettings.o
│   ├── qrc_camera.o
│   └── videosettings.o
├── .pch
├── .rcc
│   └── qrc_camera.cpp--rcc编译camera.qrc得到qrc_camera.cpp。
├── .uic
│   ├── ui_camera.h--uic编译camera.ui得到ui_camera.h。
│   ├── ui_imagesettings.h--uic编译imagesettings.ui得到ui_imagesettings.h。
│   └── ui_videosettings.h--uic编译videosettings.ui得到ui_imagesettings.h。
├── videosettings.cpp--VideoSettings类的实现。
├── videosettings.h--VideoSettings类的定义。
└── videosettings.ui--录像窗口的配置文件。

3.1 ui文件

ui文件定义了应用界面、Action、Slot/Signal及函数对应关系。

ui文件经过uic编译生成ui_*.h文件(参考Using a Designer UI File in Your C++ Application),包括:

  • 生成指向包含Widget、Action、Layout、Button等结构体。
  • setupUI()函数创建Widget树,即函数和Signal等关联操作。
  • retranslateUi()进行字符串资源处理。

使用QT Creator打开Camera如下图:

Qt中的UI文件介绍_.ui文件》《Qt的信号与槽_qt 信号槽

3.2 moc

moc 全称是 Meta-Object Compiler,也就是“元对象编译器”,它主要用于处理C++源文件中的非标准C++代码。Qt 程序在交由标准编译器编译之前,先要使用 moc 分析 C++ 源文件。如果它发现在一个头文件中包含了宏 Q_OBJECT,则会生成另外一个 C++ 源文件。这个源文件中包含了 Q_OBJECT 宏的实现代码。这个新的文件名字将会是原文件名前面加上 moc_ 构成。这个新的文件同样将进入编译系统,最终被链接到二进制代码中去。因此我们可以知道,这个新的文件不是“替换”掉旧的文件,而是与原文件一起参与编译。另外,我们还可以看出一点,moc 的执行是在预处理器之前。因为预处理器执行之后,Q_OBJECT 宏就不存在了。

参考《Qt信号与槽机制的基石-MOC详解》。

3.3 qrc文件

qrc文件是基于XML格式的资源系统配置文件(注意是配置文件而不是资源文件本身),其中指定了各种资源的信息。

将资源文件打包为二进制数据的流程是:写qrc文件 → 用rcc编译 → 二进制数据。

3.4 QCamera、QCameraInfo、QCameraExposure、QCameraFocus、QCameraFocusZone、QCameraViewfinder、QCameraViewfinderSettinfs

QCamera:系统摄像头设备接口。

QCameraInfo:有关相机设备的一般信息。

QCameraExposure:曝光相关相机设置界面。

QCameraFocus:用于对焦和变焦相关相机设置的界面。

QCameraFocusZone:有关用于相机自动对焦区域的信息。

QCameraViewfinder:用于显示摄像头实时预览。

QCameraViewfinderSettings:取景器设置。

3.5 QCameraImageCapture、QImageEncoderSettings、QCameraImageProcessing

QCameraImageCapture:拍摄照片。

QImageEncoderSettings:图像编码器设置。

QCameraImageProcessing:图像处理相关相机设置接口。

3.6 QMediaRecoder、QAudioEncoderSettings、QVideoEncoderSettings

QMediaRecoder:音视频录像。

QAudioEncoderSettings:音频编码器设置。

QVideoEncoderSettings:视频编码器设置。

3.7 camera主程序

新建的Camera,继承关系如下:Camera->QMainWindow->QWidget。

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。

代码流程如下:

main
  QApplication app--
  new Camera--生成一个QtCamera实例。
    ->ui->setupUi--调用camera.ui生成的函数,初始化Widget Layout、Button行为等等。
    ->QCameraInfo::availableCameras--获取当前可用camera列表。
    ->setCamera--打开默认Camera,注册一系列事件、错误处理函数。
      ->updateCameraState
      ->updateRecorderState
      ->updateCaptureMode--使用mplane插件。

  ->camera.show
  ->app.exec

 class Camera中定义了一系列Button/Action对应Signal函数:

class Camera : public QMainWindow
{
    Q_OBJECT

public:
    Camera();

private slots:
    void setCamera(const QCameraInfo &cameraInfo);--设置当前camera。
    void startCamera();--Start Camera菜单点击函数。
    void stopCamera();--Stop Camera菜单点击函数。

    void record();--Record按钮点击函数。
    void pause();--Pause按钮点击函数。
    void stop();--Stop按钮点击函数。
    void setMuted(bool);--Mute点击函数。

    void toggleLock();
    void takeImage();--Capture Photo按钮点击函数。
    void displayCaptureError(int, QCameraImageCapture::Error, const QString &errorString);

    void configureCaptureSettings();--Image/Video菜单点击函数。Image创建class ImageSettings实例;Video创建class VideoSettings实例。
    void configureVideoSettings();
    void configureImageSettings();

    void displayRecorderError();
    void displayCameraError();

    void updateCameraDevice(QAction *action);

    void updateCameraState(QCamera::State);
    void updateCaptureMode();
    void updateRecorderState(QMediaRecorder::State state);
    void setExposureCompensation(int index);--Exposure Compensation滑动条值改变函数。

    void updateRecordTime();--更新Video Record时间。

    void processCapturedImage(int requestId, const QImage &img);
    void updateLockStatus(QCamera::LockStatus, QCamera::LockChangeReason);

    void displayViewfinder();
    void displayCapturedImage();

    void readyForCapture(bool ready);
    void imageSaved(int id, const QString &fileName);

protected:
    void keyPressEvent(QKeyEvent *event) override;
    void keyReleaseEvent(QKeyEvent *event) override;
    void closeEvent(QCloseEvent *event) override;

private:
    Ui::Camera *ui;

    QScopedPointer<QCamera> m_camera;
    QScopedPointer<QCameraImageCapture> m_imageCapture;
    QScopedPointer<QMediaRecorder> m_mediaRecorder;

    QImageEncoderSettings m_imageSettings;
    QAudioEncoderSettings m_audioSettings;
    QVideoEncoderSettings m_videoSettings;
    QString m_videoContainerFormat;
    bool m_isCapturingImage = false;
    bool m_applicationExiting = false;
}

 

posted on 2024-04-19 23:59  ArnoldLu  阅读(476)  评论(0编辑  收藏  举报

导航