Skip to content
Snippets Groups Projects
Commit 4c0f927b authored by Morten Sorvig's avatar Morten Sorvig
Browse files

add camera example

parent db338bc9
No related branches found
No related tags found
No related merge requests found
......@@ -4,4 +4,5 @@ add_subdirectory(gallery_controls2)
add_subdirectory(rasterwindow)
add_subdirectory(principledmaterial)
add_subdirectory(hellogl)
add_subdirectory(camera)
# (slate is built separately)
\ No newline at end of file
cmake_minimum_required(VERSION 3.16)
project(camera VERSION 1.0 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Multimedia MultimediaWidgets)
find_package(Qt${QT_VERSION_MAJOR} OPTIONAL_COMPONENTS Widgets)
qt_add_executable(camera
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
)
target_link_libraries(camera PUBLIC
Qt::Core
Qt::Gui
Qt::Multimedia
Qt::MultimediaWidgets
Qt::CorePrivate
Qt::Widgets
)
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "mainwindow.h"
#include <QApplication>
#include <QLoggingCategory>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLoggingCategory::setFilterRules("*.debug=false\n"
"qt.multimedia.wasm.*=true");
MainWindow w;
w.show();
return a.exec();
}
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QAudioInput>
#include <QCamera>
#include <QCameraDevice>
#include <QGraphicsScene>
#include <QGraphicsVideoItem>
#include <QImageCapture>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QMediaFormat>
#include <QApplication>
#include <QTimer>
#include <QVideoWidget>
#include <QLabel>
#include <QFileDialog>
#include <QScreen>
#include <QMediaPlayer>
#if QT_CONFIG(permissions)
#include <QPermission>
#endif
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow),
m_recorder(nullptr)
{
ui->setupUi(this);
init();
}
MainWindow::~MainWindow()
{
if (m_recorder)
delete m_recorder;
delete ui;
}
void MainWindow::init()
{
#if QT_CONFIG(permissions)
// camera
QCameraPermission cameraPermission;
switch (qApp->checkPermission(cameraPermission)) {
case Qt::PermissionStatus::Undetermined:
qApp->requestPermission(cameraPermission, this, &MainWindow::init);
return;
case Qt::PermissionStatus::Denied:
qWarning("Camera permission is not granted!");
return;
case Qt::PermissionStatus::Granted:
break;
}
// microphone
QMicrophonePermission microphonePermission;
switch (qApp->checkPermission(microphonePermission)) {
case Qt::PermissionStatus::Undetermined:
qApp->requestPermission(microphonePermission, this, &MainWindow::init);
return;
case Qt::PermissionStatus::Denied:
qWarning("Microphone permission is not granted!");
return;
case Qt::PermissionStatus::Granted:
break;
}
#endif
m_captureSession = new QMediaCaptureSession(this);
m_mediaDevices = new QMediaDevices(this);
// wait until devices list is ready
connect(m_mediaDevices, &QMediaDevices::videoInputsChanged,
[this]() { doCamera(); });
}
void MainWindow::doCamera()
{
m_audioInput.reset(new QAudioInput);
m_captureSession->setAudioInput(m_audioInput.get());
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
ui->camerasComboBox->clear();
ui->camerasComboBox->setPlaceholderText("select camera");
for (const QCameraDevice &cameraDevice : cameras) {
if (ui->camerasComboBox->findText(cameraDevice.description()) == -1)
ui->camerasComboBox->addItem(cameraDevice.description(), cameraDevice.id());
}
if (cameras.count() == 0) {
qWarning() << "No camera found";
} else {
QGraphicsVideoItem *videoItem = new QGraphicsVideoItem();
QGraphicsScene *scene = new QGraphicsScene(this);
m_captureSession->setVideoOutput(videoItem); // sets videoSink
ui->graphicsView->setScene(scene);
ui->graphicsView->scene()->addItem(videoItem);
ui->graphicsView->show();
}
}
void MainWindow::on_startButton_clicked()
{
m_camera.data()->start();
}
void MainWindow::on_stopButton_clicked()
{
m_camera.data()->stop();
}
void MainWindow::on_captureButton_clicked()
{
connect(m_camera.data(), &QCamera::errorOccurred,
[](QCamera::Error error, const QString &errorString) {
qWarning() << "Error occurred" << error << errorString;
});
QImageCapture *m_imageCapture = new QImageCapture(this);
connect(m_imageCapture, &QImageCapture::readyForCaptureChanged, [] (bool ready) {
qWarning() << "MainWindow::readyForCaptureChanged" << ready;
});
connect(m_imageCapture,
&QImageCapture::imageCaptured,
[] (int id, const QImage &preview) {
qWarning() << "MainWindow::imageCaptured" << id << preview;
});
connect(m_imageCapture, &QImageCapture::imageSaved,
[this] (int id, const QString &fileName) {
Q_UNUSED(id)
QFileInfo fi(fileName);
if (!fi.exists()) {
qWarning() << fileName << "Does not exist";
} else {
QDialog *dlg = new QDialog(this);
dlg->setWindowTitle(fi.fileName());
QHBoxLayout *l = new QHBoxLayout(dlg);
QLabel *label = new QLabel(this);
l->addWidget(label);
label->setPixmap(QPixmap(fileName));
dlg->show();
}
});
connect(m_imageCapture,
&QImageCapture::errorOccurred, []
(int id, QImageCapture::Error error, const QString &errorString) {
qWarning() << "MainWindow::errorOccurred" << id << error << errorString;
});
m_captureSession->setImageCapture(m_imageCapture);
// take photo
if (m_imageCapture->isReadyForCapture())
m_imageCapture->captureToFile(QStringLiteral("/home/web_user/image.png"));
}
void MainWindow::on_openButton_clicked()
{
// open
QFileDialog *dialog = new QFileDialog(this);
dialog->setNameFilter(tr("All Files (*.*)"));
connect(dialog, &QFileDialog::fileSelected,
[this](const QString &file) {
qWarning() << "open this file" << file;
showFile(file);
});
dialog->show();
}
void MainWindow::on_camerasComboBox_textActivated(const QString &arg1)
{
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
for (const QCameraDevice &cameraDevice :cameras) {
if (arg1 == cameraDevice.description()) {
m_camera.reset(new QCamera(cameraDevice));
connect(m_captureSession, &QMediaCaptureSession::cameraChanged,
[this]() {
enableButtons(true);
});
m_captureSession->setCamera(m_camera.data());
break;
}
}
}
void MainWindow::on_recordButton_clicked()
{
if (!isRecording) {
if (m_recorder)
delete m_recorder;
m_recorder = new QMediaRecorder();
connect(m_recorder, &QMediaRecorder::durationChanged,
[](qint64 duration) {
qWarning() << "MainWindow::durationChanged"
<< duration;
});
m_captureSession->setRecorder(m_recorder);
m_recorder->setQuality(QMediaRecorder::HighQuality);
m_recorder->setOutputLocation(QUrl::fromLocalFile("test.mp4"));
m_recorder->record();
isRecording = true;
ui->recordButton->setText(QStringLiteral("Stop"));
} else {
m_recorder->stop();
isRecording = false;
m_recorder->deleteLater();
ui->recordButton->setText(QStringLiteral("Record"));
}
}
void MainWindow::enableButtons(bool ok)
{
ui->captureButton->setEnabled(ok);
ui->startButton->setEnabled(ok);
ui->stopButton->setEnabled(ok);
ui->openButton->setEnabled(ok);
ui->recordButton->setEnabled(ok);
}
void MainWindow::showFile(const QString &fileName)
{
const QSize screenGeometry = screen()->availableSize();
QFileInfo fi(fileName);
QDialog *dlg = new QDialog(this);
dlg->setWindowTitle(fi.fileName());
QHBoxLayout *layout = new QHBoxLayout(dlg);
QMediaPlayer *player = new QMediaPlayer(dlg);
connect(player, &QMediaPlayer::errorOccurred, [=] (QMediaPlayer::Error error, const QString &errorString) {
qWarning() << "MediaPlayer erro!:" << error << errorString;
});
QGraphicsVideoItem *m_videoItem = new QGraphicsVideoItem();
QSizeF dialogSize(screenGeometry.width() / 2, screenGeometry.height() / 2);
m_videoItem->setSize(dialogSize);
player->setVideoOutput(m_videoItem);
dlg->setGeometry(20, 20, dialogSize.width() + 40, dialogSize.height() + 40);
QGraphicsScene *scene = new QGraphicsScene(dlg);
QGraphicsView *graphicsView = new QGraphicsView(scene);
scene->addItem(m_videoItem);
layout->addWidget(graphicsView);
player->setSource(QUrl(fileName));
dlg->show();
player->play();
}
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QImageCapture>
#include <QMediaCaptureSession>
#include <QGraphicsVideoItem>
#include <QCamera>
#include <QMediaDevices>
#include <QMediaRecorder>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
class QMediaCaptureSession;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void init();
private slots:
void doCamera();
void on_startButton_clicked();
void on_stopButton_clicked();
void on_captureButton_clicked();
void on_openButton_clicked();
void on_recordButton_clicked();
void on_camerasComboBox_textActivated(const QString &arg1);
private:
Ui::MainWindow *ui;
void enableButtons(bool ok);
void showFile(const QString &filename);
QScopedPointer<QCamera> m_camera;
QMediaCaptureSession *m_captureSession;
QScopedPointer<QAudioInput> m_audioInput;
QMediaDevices *m_mediaDevices;
QMediaRecorder *m_recorder;
bool isRecording = false;
};
QT_END_NAMESPACE
#endif // MAINWINDOW_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="camerasComboBox">
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string/>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QGraphicsView" name="graphicsView"/>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="startButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>start camera</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>stop camera</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="captureButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>capture photo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="recordButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>record</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="openButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>open</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
......@@ -34,6 +34,7 @@ deploy "multicanvas"
deploy "rasterwindow"
deploy "principledmaterial"
deploy "hellogl"
deploy "camera"
# slate
rm -rf slate
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment