From 5dc589aee074d42e42a96adca189d4ddcf0d14b7 Mon Sep 17 00:00:00 2001 From: tangchao0503 <735056338@qq.com> Date: Wed, 27 May 2026 14:36:46 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=8C=E5=8D=95=E5=8F=8D=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA2=EF=BC=9A=201=E3=80=81=E5=AE=9E=E7=8E=B03s=E6=8B=8D?= =?UTF-8?q?=E7=85=A7=EF=BC=9B=202=E3=80=81=E8=AE=BE=E7=BD=AE=E7=85=A7?= =?UTF-8?q?=E7=89=87=E4=BF=9D=E5=AD=98=E8=B7=AF=E5=BE=84=EF=BC=9B=203?= =?UTF-8?q?=E3=80=81=E8=BD=AE=E6=92=AD=E7=9C=8B=E6=9D=BF=EF=BC=9A=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=8D=95=E5=8F=8D=E5=AE=9E=E6=97=B6=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=B5=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HPPA/AppSettings.cpp | 21 ++ HPPA/AppSettings.h | 5 + HPPA/HPPA.cpp | 43 ++++ HPPA/HPPA.h | 4 + HPPA/SingleLensReflexCamera.ui | 85 +++++-- HPPA/SingleLensReflexCameraWindow.cpp | 325 ++++++++++++++++++++++++-- HPPA/SingleLensReflexCameraWindow.h | 62 ++++- 7 files changed, 509 insertions(+), 36 deletions(-) diff --git a/HPPA/AppSettings.cpp b/HPPA/AppSettings.cpp index fc8ffae..b972dff 100644 --- a/HPPA/AppSettings.cpp +++ b/HPPA/AppSettings.cpp @@ -1,10 +1,12 @@ #include "AppSettings.h" +#include const QString AppSettings::kDefaultDataFolder = QStringLiteral("C:\\HPPA_image"); const QString AppSettings::kDefaultFileName = QStringLiteral("test_image"); const int AppSettings::kDefaultFrameRate = 20; const int AppSettings::kDefaultIntegrationTime = 1; const int AppSettings::kDefaultGain = 0; +const QString AppSettings::kDefaultSLRDataFolder = QString(); AppSettings::AppSettings() : m_settings(QSettings::IniFormat, QSettings::UserScope, @@ -32,6 +34,7 @@ QString AppSettings::fileName() const { return m_settings.value("General/FileName", kDefaultFileName).toString(); } + void AppSettings::setFileName(const QString& path) { m_settings.setValue("General/FileName", path); @@ -41,6 +44,7 @@ int AppSettings::frameRate() const { return m_settings.value("CameraParams/FrameRate", kDefaultFrameRate).toInt(); } + void AppSettings::setFrameRate(int value) { m_settings.setValue("CameraParams/FrameRate", value); @@ -50,6 +54,7 @@ int AppSettings::integrationTime() const { return m_settings.value("CameraParams/IntegrationTime", kDefaultIntegrationTime).toInt(); } + void AppSettings::setIntegrationTime(int value) { m_settings.setValue("CameraParams/IntegrationTime", value); @@ -59,7 +64,23 @@ int AppSettings::gain() const { return m_settings.value("CameraParams/Gain", kDefaultGain).toInt(); } + void AppSettings::setGain(int value) { m_settings.setValue("CameraParams/Gain", value); } + +QString AppSettings::slrDataFolder() const +{ + QString path = m_settings.value("General/SLRDataFolder").toString(); + if (path.isEmpty()) + { + return QCoreApplication::applicationDirPath() + "/CapturedImages/"; + } + return path; +} + +void AppSettings::setSlrDataFolder(const QString& path) +{ + m_settings.setValue("General/SLRDataFolder", path); +} diff --git a/HPPA/AppSettings.h b/HPPA/AppSettings.h index e25e72a..0bbad84 100644 --- a/HPPA/AppSettings.h +++ b/HPPA/AppSettings.h @@ -26,6 +26,10 @@ public: // 增益 int gain() const; void setGain(int value); + + // 单反相机数据保存路径 + QString slrDataFolder() const; + void setSlrDataFolder(const QString& path); // 在此处添加更多参数的 getter/setter ... private: @@ -41,4 +45,5 @@ private: static const int kDefaultFrameRate; static const int kDefaultIntegrationTime; static const int kDefaultGain; + static const QString kDefaultSLRDataFolder; }; diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 7995ee3..3b451c1 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -385,6 +385,7 @@ HPPA::HPPA(QWidget* parent) m_carousel = new MyCarousel(); m_carousel->setObjectName(QString::fromUtf8("carousel")); + //--------------------------------------------------------------------- QScrollArea* sa = new QScrollArea(); sa->setObjectName("sa"); sa->setStyleSheet(R"( @@ -430,6 +431,29 @@ HPPA::HPPA(QWidget* parent) m_carousel->addWidget(sa_depthCamera); m_carousel->setContentsMargins(0, 0, 0, 0); + //--------------------------------------------------------------------- + QScrollArea* sa_SingleLensReflexCamera = new QScrollArea(); + sa_SingleLensReflexCamera->setObjectName("sa_SingleLensReflexCamera"); + sa_SingleLensReflexCamera->setStyleSheet(R"( + border: none; + background-color: #0D1233; + )"); + QGridLayout* gridLayout_sa_SingleLensReflexCamera = new QGridLayout(sa_SingleLensReflexCamera); + gridLayout_sa_SingleLensReflexCamera->setSpacing(6); + gridLayout_sa_SingleLensReflexCamera->setObjectName(QString::fromUtf8("gridLayout_sa_SingleLensReflexCamera")); + gridLayout_sa_SingleLensReflexCamera->setVerticalSpacing(0); + gridLayout_sa_SingleLensReflexCamera->setContentsMargins(0, 0, 0, 0); + + m_SingleLensReflexCamera_label = new QLabel(); + m_SingleLensReflexCamera_label->setAlignment(Qt::AlignHCenter); + m_SingleLensReflexCamera_label->setStyleSheet(R"( + background-color: #0D1233; + )"); + gridLayout_sa_SingleLensReflexCamera->addWidget(m_SingleLensReflexCamera_label); + + m_carousel->addWidget(sa_SingleLensReflexCamera); + m_carousel->setContentsMargins(0, 0, 0, 0); + m_carousel->play(); gridLayout_carouselContainer->addWidget(m_carousel); @@ -784,6 +808,9 @@ void HPPA::initControlTabwidget() //单反相机 m_singleLensReflexCameraWindow = new SingleLensReflexCameraWindow(); + connect(m_singleLensReflexCameraWindow, &SingleLensReflexCameraWindow::LiveViewImageReady, this, &HPPA::onLiveViewImageReady); + connect(m_singleLensReflexCameraWindow, &SingleLensReflexCameraWindow::LiveViewStopped, this, &HPPA::onLiveViewStopped); + ui.controlTabWidget->addTab(m_singleLensReflexCameraWindow, QString::fromLocal8Bit("单反相机")); //rgb相机 @@ -1892,6 +1919,22 @@ void HPPA::onClearLabel() m_cam_label->setText("closed"); } +void HPPA::onLiveViewImageReady(const QImage& image) +{ + if (m_SingleLensReflexCamera_label && !image.isNull()) + { + // 缩放图像以适应标签大小 + QPixmap pixmap = QPixmap::fromImage(image); + pixmap = pixmap.scaled(m_SingleLensReflexCamera_label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + m_SingleLensReflexCamera_label->setPixmap(pixmap); + } +} + +void HPPA::onLiveViewStopped() +{ + m_SingleLensReflexCamera_label->clear(); +} + void HPPA::onPlotDepthImage() { QPixmap pixmap = QPixmap::fromImage(m_depthCameraWindow->m_DepthCameraOperation->m_depthImage); diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h index 542c616..0cfe0d0 100644 --- a/HPPA/HPPA.h +++ b/HPPA/HPPA.h @@ -274,6 +274,7 @@ private: MyCarousel* m_carousel; QLabel* m_cam_label; + QLabel* m_SingleLensReflexCamera_label; QLabel* m_depthCamera_label; QPushButton* m_open_rgb_camera_btn; QPushButton* m_close_rgb_camera_btn; @@ -358,6 +359,9 @@ public Q_SLOTS: void onPlotRgbImage(); void onPlotDepthImage(); + void onLiveViewImageReady(const QImage& image); + void HPPA::onLiveViewStopped(); + void onClearLabel(); void onClearDepthLabel(); diff --git a/HPPA/SingleLensReflexCamera.ui b/HPPA/SingleLensReflexCamera.ui index a250198..28093f4 100644 --- a/HPPA/SingleLensReflexCamera.ui +++ b/HPPA/SingleLensReflexCamera.ui @@ -69,7 +69,7 @@ QPushButton:pressed padding-bottom: 7px; } - + @@ -97,21 +97,8 @@ QPushButton:pressed - - - - - - 0 - 0 - - - - 关 闭 - - - - + + @@ -124,9 +111,22 @@ QPushButton:pressed + + + + + 0 + 0 + + + + 关 闭 + + + - + Qt::Horizontal @@ -139,7 +139,52 @@ QPushButton:pressed - + + + + + + QLabel { + color: rgb(255, 255, 255); +} + + + 数据路径 + + + + + + + QLineEdit { + background-color: #142D7F; + color: #e6eeff; + border: 1px solid #2f6bff; + border-radius: 6px; + padding: 4px 8px; + min-width: 70px; + min-height: 20px; + font-size: 13px; +} + + + ./CapturedImages + + + true + + + + + + + ... + + + + + + Qt::Vertical @@ -153,6 +198,10 @@ QPushButton:pressed + dataFolderLineEdit + dataFolderBtn + label + openSLRCamera_btn diff --git a/HPPA/SingleLensReflexCameraWindow.cpp b/HPPA/SingleLensReflexCameraWindow.cpp index 0ed2af9..7a8e3e9 100644 --- a/HPPA/SingleLensReflexCameraWindow.cpp +++ b/HPPA/SingleLensReflexCameraWindow.cpp @@ -1,12 +1,14 @@ #include "SingleLensReflexCameraWindow.h" #include #include +#include // 全局变量用于回调函数访问 static SingleLensReflexCameraOperation* g_cameraOperation = nullptr; SingleLensReflexCameraWindow::SingleLensReflexCameraWindow(QWidget* parent) : QDialog(parent) + , m_isCapturing(false) { ui.setupUi(this); @@ -15,24 +17,39 @@ SingleLensReflexCameraWindow::SingleLensReflexCameraWindow(QWidget* parent) m_SingleLensReflexCameraOperation->moveToThread(m_SLRCameraThread); m_SLRCameraThread->start(); + // 基本连接 connect(ui.openSLRCamera_btn, &QPushButton::clicked, this, &SingleLensReflexCameraWindow::openSLRCamera); + connect(this, &SingleLensReflexCameraWindow::openSLRCameraSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::OpenSLRCamera); connect(ui.closeSLRCamera_btn, &QPushButton::clicked, this, &SingleLensReflexCameraWindow::closeSLRCamera); connect(this, &SingleLensReflexCameraWindow::closeSLRCameraSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CloseSLRCamera); - connect(this, &SingleLensReflexCameraWindow::openSLRCameraSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::OpenSLRCamera); - connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamOpenedSignal, this, &SingleLensReflexCameraWindow::onCamOpened); connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamClosedSignal, this, &SingleLensReflexCameraWindow::onCamClosed); connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::PlotSignal, this, &SingleLensReflexCameraWindow::PlotSLRImageSignal); connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamClosedSignal, this, &SingleLensReflexCameraWindow::SLRCamClosedSignal); + connect(this->ui.dataFolderBtn, SIGNAL(clicked()), this, SLOT(onSelectDataFolder())); + // 新增信号连接 connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::ImageCapturedSignal, this, &SingleLensReflexCameraWindow::onImageCaptured); connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::ErrorSignal, this, &SingleLensReflexCameraWindow::onError); + // 实时取景信号连接 + connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::LiveViewImageReady, this, &SingleLensReflexCameraWindow::LiveViewImageReady, Qt::QueuedConnection); + connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::LiveViewStarted, this, &SingleLensReflexCameraWindow::LiveViewStarted); + connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::LiveViewStopped, this, &SingleLensReflexCameraWindow::LiveViewStopped); + + // 拍照控制信号连接 + connect(this, &SingleLensReflexCameraWindow::startCaptureSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::startCapture); + connect(this, &SingleLensReflexCameraWindow::stopCaptureSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::stopCapture); + connect(this, &SingleLensReflexCameraWindow::captureOnceSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::captureOnce); + // 初始化按钮状态 ui.closeSLRCamera_btn->setEnabled(false); + + // 初始化数据保存路径显示(从 AppSettings 恢复或使用默认) + ui.dataFolderLineEdit->setText(AppSettings::instance().slrDataFolder()); } SingleLensReflexCameraWindow::~SingleLensReflexCameraWindow() @@ -49,6 +66,23 @@ SingleLensReflexCameraWindow::~SingleLensReflexCameraWindow() m_SingleLensReflexCameraOperation = nullptr; } +void SingleLensReflexCameraWindow::onSelectDataFolder() +{ + QString dir = QFileDialog::getExistingDirectory(this, + QString::fromLocal8Bit("选择数据保存路径"), + ui.dataFolderLineEdit->text()); + + if (!dir.isEmpty()) + { + ui.dataFolderLineEdit->setText(dir); + + m_SingleLensReflexCameraOperation->setSavePath(dir); + + // 保存路径到 AppSettings + AppSettings::instance().setSlrDataFolder(dir); + } +} + void SingleLensReflexCameraWindow::openSLRCamera() { if (!m_SingleLensReflexCameraOperation->getRecordStatus()) @@ -66,7 +100,7 @@ void SingleLensReflexCameraWindow::onCamOpened() void SingleLensReflexCameraWindow::closeSLRCamera() { - emit closeSLRCameraSignal(); + emit closeSLRCameraSignal(); //m_SingleLensReflexCameraOperation->CloseSLRCamera(); } @@ -75,6 +109,7 @@ void SingleLensReflexCameraWindow::onCamClosed() ui.openSLRCamera_btn->setEnabled(true); ui.closeSLRCamera_btn->setEnabled(false); ui.openSLRCamera_btn->setText(QString::fromLocal8Bit("打 开")); + m_isCapturing = false; } void SingleLensReflexCameraWindow::onImageCaptured(const QString& filePath) @@ -88,6 +123,29 @@ void SingleLensReflexCameraWindow::onError(const QString& errorMsg) QMessageBox::warning(this, QString::fromLocal8Bit("相机错误"), errorMsg); } +void SingleLensReflexCameraWindow::onStartCapture() +{ + if (!m_isCapturing) + { + m_isCapturing = true; + emit startCaptureSignal(); + } +} + +void SingleLensReflexCameraWindow::onStopCapture() +{ + if (m_isCapturing) + { + m_isCapturing = false; + emit stopCaptureSignal(); + } +} + +void SingleLensReflexCameraWindow::onCaptureOnce() +{ + emit captureOnceSignal(); +} + //------------------------------------------------------------------------------------------------------------------------------- // SingleLensReflexCameraOperation 实现 //------------------------------------------------------------------------------------------------------------------------------- @@ -99,11 +157,13 @@ SingleLensReflexCameraOperation::SingleLensReflexCameraOperation() m_camera = nullptr; m_isSDKInitialized = false; m_isSessionOpen = false; + m_isLiveViewActive = false; m_captureTimer = nullptr; + m_liveViewTimer = nullptr; m_imageCounter = 0; - // 设置保存路径(可以根据需要修改) - m_savePath = QCoreApplication::applicationDirPath() + "/CapturedImages/"; + // 设置保存路径(从 AppSettings 获取,如果为空则使用默认的 CapturedImages 目录) + m_savePath = AppSettings::instance().slrDataFolder(); // 创建保存目录 QDir dir; @@ -124,6 +184,27 @@ SingleLensReflexCameraOperation::~SingleLensReflexCameraOperation() g_cameraOperation = nullptr; } +void SingleLensReflexCameraOperation::setSavePath(const QString& path) +{ + m_savePath = path; + if (!m_savePath.endsWith('/') && !m_savePath.endsWith('\\')) + { + m_savePath += '/'; + } + + QDir dir; + if (!dir.exists(m_savePath)) + { + dir.mkpath(m_savePath); + } +} + +QImage SingleLensReflexCameraOperation::getCurrentLiveViewImage() +{ + QMutexLocker locker(&m_liveViewMutex); + return m_liveViewImage.copy(); +} + EdsError SingleLensReflexCameraOperation::initializeSDK() { EdsError err = EdsInitializeSDK(); @@ -272,10 +353,165 @@ EdsError SingleLensReflexCameraOperation::setupSaveToHost() return EDS_ERR_OK; } +EdsError SingleLensReflexCameraOperation::startLiveView() +{ + EdsError err = EDS_ERR_OK; + + if (m_camera == nullptr || !m_isSessionOpen) + { + return EDS_ERR_DEVICE_NOT_FOUND; + } + + // 获取当前输出设备设置 + EdsUInt32 device = 0; + err = EdsGetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to get Evf_OutputDevice, error: " << err << std::endl; + // 某些相机可能不支持获取,继续尝试设置 + } + + // 设置PC为实时取景输出设备 + device |= kEdsEvfOutputDevice_PC; + err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to set Evf_OutputDevice, error: " << err << std::endl; + return err; + } + + m_isLiveViewActive = true; + std::cout << "Live view started" << std::endl; + + emit LiveViewStarted(); + + return EDS_ERR_OK; +} + +EdsError SingleLensReflexCameraOperation::stopLiveView() +{ + EdsError err = EDS_ERR_OK; + + if (m_camera == nullptr || !m_isSessionOpen) + { + m_isLiveViewActive = false; + return EDS_ERR_OK; + } + + // 获取当前输出设备设置 + EdsUInt32 device = 0; + err = EdsGetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to get Evf_OutputDevice, error: " << err << std::endl; + } + + // 从输出设备中移除PC + device &= ~kEdsEvfOutputDevice_PC; + err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to clear Evf_OutputDevice, error: " << err << std::endl; + } + + m_isLiveViewActive = false; + std::cout << "Live view stopped" << std::endl; + + emit LiveViewStopped(); + + return EDS_ERR_OK; +} + +EdsError SingleLensReflexCameraOperation::downloadEvfImage() +{ + EdsError err = EDS_ERR_OK; + EdsStreamRef stream = nullptr; + EdsEvfImageRef evfImage = nullptr; + + if (m_camera == nullptr || !m_isLiveViewActive) + { + return EDS_ERR_DEVICE_NOT_FOUND; + } + + // 创建内存流 + err = EdsCreateMemoryStream(0, &stream); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to create memory stream, error: " << err << std::endl; + return err; + } + + // 创建实时取景图像引用 + err = EdsCreateEvfImageRef(stream, &evfImage); + if (err != EDS_ERR_OK) + { + std::cout << "Failed to create evf image ref, error: " << err << std::endl; + EdsRelease(stream); + return err; + } + + // 下载实时取景图像 + err = EdsDownloadEvfImage(m_camera, evfImage); + if (err != EDS_ERR_OK) + { + // EDS_ERR_OBJECT_NOTREADY 是正常的,表示图像还没准备好 + if (err != EDS_ERR_OBJECT_NOTREADY) + { + std::cout << "Failed to download evf image, error: " << err << std::endl; + } + EdsRelease(evfImage); + EdsRelease(stream); + return err; + } + + // 获取流数据 + EdsVoid* pData = nullptr; + EdsUInt64 length = 0; + + err = EdsGetPointer(stream, &pData); + if (err != EDS_ERR_OK) + { + EdsRelease(evfImage); + EdsRelease(stream); + return err; + } + + err = EdsGetLength(stream, &length); + if (err != EDS_ERR_OK || length == 0) + { + EdsRelease(evfImage); + EdsRelease(stream); + return err; + } + + // 将JPEG数据转换为QImage + QImage image; + if (image.loadFromData(static_cast(pData), static_cast(length), "JPEG")) + { + QMutexLocker locker(&m_liveViewMutex); + m_liveViewImage = image.copy(); + locker.unlock(); + + // 发送信号通知图像已准备好 + emit LiveViewImageReady(image); + } + + // 释放资源 + EdsRelease(evfImage); + EdsRelease(stream); + + return EDS_ERR_OK; +} + EdsError SingleLensReflexCameraOperation::takePicture() { EdsError err = EDS_ERR_OK; + if (m_camera == nullptr || !m_isSessionOpen) + { + return EDS_ERR_DEVICE_NOT_FOUND; + } + // 按下快门 err = EdsSendCommand(m_camera, kEdsCameraCommand_PressShutterButton, kEdsCameraCommand_ShutterButton_Completely); if (err != EDS_ERR_OK) @@ -459,16 +695,30 @@ void SingleLensReflexCameraOperation::OpenSLRCamera() return; } + // 启动实时取景 + err = startLiveView(); + if (err != EDS_ERR_OK) + { + std::cout << "Warning: Failed to start live view, error: " << err << std::endl; + // 实时取景启动失败不是致命错误,继续执行 + } + record = true; - // 创建并启动定时器(1秒拍一张) + // 创建实时取景定时器(约30fps) + m_liveViewTimer = new QTimer(this); + connect(m_liveViewTimer, &QTimer::timeout, this, &SingleLensReflexCameraOperation::onLiveViewTimer); + m_liveViewTimer->start(33); // 约30fps + + // 创建拍照定时器(1秒拍一张),但不立即启动 m_captureTimer = new QTimer(this); connect(m_captureTimer, &QTimer::timeout, this, &SingleLensReflexCameraOperation::onCaptureTimer); - m_captureTimer->start(2000); // 1000毫秒 = 1秒 + // 默认启动定时拍照 + m_captureTimer->start(3000); // 1000毫秒 = 1秒 emit CamOpenedSignal(); - std::cout << "Camera opened and timer started (1 photo per second)" << std::endl; + std::cout << "Camera opened, live view started, capture timer started (1 photo per second)" << std::endl; } void SingleLensReflexCameraOperation::OpenSLRCamera_callback() @@ -481,6 +731,20 @@ void SingleLensReflexCameraOperation::setCallback(void(*func)()) m_func = func; } +void SingleLensReflexCameraOperation::onLiveViewTimer() +{ + if (!record || !m_isLiveViewActive) + { + return; + } + + // 处理相机事件 + EdsGetEvent(); + + // 下载实时取景图像 + downloadEvfImage(); +} + void SingleLensReflexCameraOperation::onCaptureTimer() { if (!record) @@ -490,9 +754,6 @@ void SingleLensReflexCameraOperation::onCaptureTimer() QMutexLocker locker(&m_mutex); - // 处理相机事件(重要:需要定期调用以接收回调) - EdsGetEvent(); - // 拍照 EdsError err = takePicture(); if (err != EDS_ERR_OK) @@ -509,6 +770,33 @@ void SingleLensReflexCameraOperation::onCaptureTimer() std::cout << "Total pictures taken: " << m_imageCounter << std::endl; } +void SingleLensReflexCameraOperation::startCapture() +{ + if (m_captureTimer && !m_captureTimer->isActive()) + { + m_captureTimer->start(1000); + std::cout << "Capture timer started" << std::endl; + } +} + +void SingleLensReflexCameraOperation::stopCapture() +{ + if (m_captureTimer && m_captureTimer->isActive()) + { + m_captureTimer->stop(); + std::cout << "Capture timer stopped" << std::endl; + } +} + +void SingleLensReflexCameraOperation::captureOnce() +{ + if (record) + { + QMutexLocker locker(&m_mutex); + takePicture(); + } +} + void SingleLensReflexCameraOperation::CloseSLRCamera() { std::cout << "SingleLensReflexCameraOperation::CloseSLRCamera,关闭单反相机" << std::endl; @@ -517,7 +805,7 @@ void SingleLensReflexCameraOperation::CloseSLRCamera() record = false; - // 停止定时器 + // 停止拍照定时器 if (m_captureTimer != nullptr) { m_captureTimer->stop(); @@ -525,6 +813,17 @@ void SingleLensReflexCameraOperation::CloseSLRCamera() m_captureTimer = nullptr; } + // 停止实时取景定时器 + if (m_liveViewTimer != nullptr) + { + m_liveViewTimer->stop(); + delete m_liveViewTimer; + m_liveViewTimer = nullptr; + } + + // 停止实时取景 + stopLiveView(); + // 处理剩余事件 for (int i = 0; i < 10; i++) { @@ -542,4 +841,4 @@ void SingleLensReflexCameraOperation::CloseSLRCamera() m_imageCounter = 0; emit CamClosedSignal(); -} \ No newline at end of file +} diff --git a/HPPA/SingleLensReflexCameraWindow.h b/HPPA/SingleLensReflexCameraWindow.h index 64b145c..4fcc603 100644 --- a/HPPA/SingleLensReflexCameraWindow.h +++ b/HPPA/SingleLensReflexCameraWindow.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include "ui_SingleLensReflexCamera.h" @@ -37,21 +39,34 @@ public: QImage m_depthImage; void setCallback(void(*func)()); bool getRecordStatus() const { return record; } + + // 设置保存路径 + void setSavePath(const QString& path); + + // 获取当前实时取景图像 + QImage getCurrentLiveViewImage(); private: cv::Mat frame; func m_func; bool record; - + // Canon EDSDK相关成员 EdsCameraRef m_camera; bool m_isSDKInitialized; bool m_isSessionOpen; - QTimer* m_captureTimer; + bool m_isLiveViewActive; + + QTimer* m_captureTimer; // 拍照定时器 + QTimer* m_liveViewTimer; // 实时取景定时器 + QString m_savePath; int m_imageCounter; QMutex m_mutex; - + QMutex m_liveViewMutex; + + QImage m_liveViewImage; // 当前实时取景图像 + // EDSDK辅助函数 EdsError initializeSDK(); EdsError terminateSDK(); @@ -59,12 +74,17 @@ private: EdsError closeCamera(); EdsError takePicture(); EdsError setupSaveToHost(); - + + // 实时取景相关函数 + EdsError startLiveView(); + EdsError stopLiveView(); + EdsError downloadEvfImage(); + // 静态回调函数 static EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event, EdsBaseRef object, EdsVoid* context); static EdsError EDSCALLBACK handlePropertyEvent(EdsPropertyEvent event, EdsPropertyID property, EdsUInt32 param, EdsVoid* context); static EdsError EDSCALLBACK handleStateEvent(EdsStateEvent event, EdsUInt32 parameter, EdsVoid* context); - + // 下载图像 EdsError downloadImage(EdsDirectoryItemRef directoryItem); @@ -73,6 +93,12 @@ public slots: void OpenSLRCamera_callback(); void CloseSLRCamera(); void onCaptureTimer(); + void onLiveViewTimer(); + + // 控制拍照 + void startCapture(); // 开始定时拍照 + void stopCapture(); // 停止定时拍照 + void captureOnce(); // 拍一张照片 signals: void PlotSignal(); @@ -80,6 +106,11 @@ signals: void CamClosedSignal(); void ImageCapturedSignal(const QString& filePath); void ErrorSignal(const QString& errorMsg); + + // 实时取景信号 + void LiveViewImageReady(const QImage& image); + void LiveViewStarted(); + void LiveViewStopped(); }; class SingleLensReflexCameraWindow : public QDialog @@ -93,20 +124,41 @@ public: SingleLensReflexCameraOperation* m_SingleLensReflexCameraOperation; public Q_SLOTS: + void onSelectDataFolder(); + void openSLRCamera(); void onCamOpened(); void closeSLRCamera(); void onCamClosed(); void onImageCaptured(const QString& filePath); void onError(const QString& errorMsg); + + // 拍照控制 + void onStartCapture(); + void onStopCapture(); + void onCaptureOnce(); signals: void openSLRCameraSignal(); void closeSLRCameraSignal(); void PlotSLRImageSignal(); void SLRCamClosedSignal(); + + // 控制信号 + void startCaptureSignal(); + void stopCaptureSignal(); + void captureOnceSignal(); + // 实时取景信号 + void LiveViewImageReady(const QImage& image); + void LiveViewStarted(); + void LiveViewStopped(); private: Ui::SingleLensReflexCameraClass ui; QThread* m_SLRCameraThread; + + // 用于显示实时取景的标签(如果UI中没有,可以动态创建) + QLabel* m_liveViewLabel; + + bool m_isCapturing; // 是否正在定时拍照 };