Common Vision Blox 15.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Friends Modules Pages
cvb_movie2/Cvb++/QtMovie2

This example program is located in your CVB installation under %CVB%Tutorial/cvb_movie2/Cvb++/QtMovie2.

main.cpp:

#ifdef _MSC_VER
#pragma warning ( push, 1)
#pragma warning ( disable : 4702)
#endif
#include <QApplication>
#include <QIcon>
#include "main_widget.hpp"
#ifdef _MSC_VER
#pragma warning ( pop)
#endif
int main(int argc, char* argv[])
{
QApplication application(argc, argv);
MainWidget mainWidget;
mainWidget.setWindowIcon(QIcon(":/qttutorial.png"));
mainWidget.show();
application.exec();
}

main_widget.cpp:

//
#include "main_widget.hpp"
#include <QDir>
#include <QFileDialog>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QMessageBox>
#include <QComboBox>
#include <cvb/image.hpp>
#include <cvb/device_factory.hpp>
#include <cvb/device.hpp>
#include <cvb/driver/driver.hpp>
#include <cvb/driver/stream.hpp>
#include <cvb/size_2d.hpp>
#include <cvb/movie2/recorder.hpp>
#include <cvb/movie2/recording_settings.hpp>
MainWidget::MainWidget()
: QWidget()
{
auto layout = new QGridLayout;
auto fileName = QDir::homePath() + QDir::separator() + "Documents" + QDir::separator() + "Movie2ExampleVideo.avi";
movieFile_ = new QLineEdit(fileName);
auto btnFileSelect = new QPushButton("Record to...");
QObject::connect(btnFileSelect, &QPushButton::clicked, [=]() {
auto file = QFileDialog::getSaveFileName(this, "Record Video", fileName, "Video Files (*.avi)");
if (file.isEmpty())
file = fileName;
movieFile_->setText(file);
});
imageView_ = new Cvb::UI::ImageView;
imageView_->SetUploadMode(Cvb::UI::UploadMode::Viewport);
imageView_->SetRenderEngine(Cvb::UI::RenderEngine::Raster);
imageView_->resize(800, 600);
QPushButton* openImgBtn = new QPushButton("Open Image");
QObject::connect(openImgBtn, &QPushButton::clicked, [=]()
{
auto driver = QFileDialog::getOpenFileName(this, "Load Image"
, Cvb::UI::CvbToQt(Cvb::InstallPath() + CVB_LIT("tutorial"))
, "CVB Emulator Image Lists (*.emu);;CVB Drivers (*.vin);;Images (*.bmp *.png *.tif *.tiff *.jpg)");
Load(driver);
});
grabCheckBox_ = new QCheckBox("Grab");
QObject::connect(grabCheckBox_, &QCheckBox::stateChanged, [=](int state)
{
if (state == Qt::CheckState::Checked)
{
// Start streaming
streamHandler_->Run();
assert(streamHandler_->IsActive());
}
else
{
// Disable possible blocking of the UI if necessary
bool wait = imageView_->IsWaitForRepaintEnabled();
if (wait)
imageView_->SetWaitForRepaintEnabled(!wait);
// Stop streaming
streamHandler_->Finish();
// Reset the previous state
imageView_->SetWaitForRepaintEnabled(wait);
assert(!streamHandler_->IsActive());
}
});
auto recordCheckBox = new QCheckBox("Record");
QObject::connect(recordCheckBox, &QPushButton::clicked, [=]()
{
if (!recorder_)
{
// Start recording, Write to avi file is in HandleAsyncStream
recorder_ = Cvb::Movie2::Recorder::Create(Cvb::UI::QtToCvb(movieFile_->text()), imageView_->Image()->Size(),
Cvb::Movie2::RecorderPixelFormat::Mono, settings_);
}
else
{
// Stop recording (necessary to close the recording file correctly)
recorder_.reset();
}
});
// Show recording codecs of direct show engine
auto codecComboBox = new QComboBox();
auto codecs = settings_.AvailableCodecs();
for(const auto & codec : codecs)
codecComboBox->addItem(Cvb::UI::CvbToQt(codec));
codecComboBox->setCurrentText(Cvb::UI::CvbToQt(settings_.Codec()));
layout->addWidget(btnFileSelect, 0, 0);
layout->addWidget(movieFile_, 0, 1);
layout->addWidget(openImgBtn, 0, 2);
layout->addWidget(grabCheckBox_, 0, 3);
layout->addWidget(recordCheckBox, 1, 2, 1, 2);
layout->addWidget(codecComboBox, 2, 2, 1, -1);
layout->addWidget(imageView_, 1, 0, 3, 2);
Load(Cvb::UI::CvbToQt(Cvb::InstallPath() + CVB_LIT("tutorial/ClassicSwitch.emu")));
setLayout(layout);
}
// Load an image or driver
void MainWidget::Load(const QString& driver)
{
QString fileName = driver;
if (fileName.isEmpty())
return;
if (fileName.contains(".emu", Qt::CaseInsensitive))
fileName = fileName.replace("/", "\\"); // necessary for emu files
try
{
// Either load an image or device (vin or emu)
if (fileName.contains(".bmp", Qt::CaseInsensitive) || fileName.contains(".png", Qt::CaseInsensitive) || fileName.contains(".tif", Qt::CaseInsensitive) || fileName.contains(".jpg", Qt::CaseInsensitive))
{
imageView_->Refresh(image);
// Disable the grab check box for images
grabCheckBox_->setEnabled(false);
}
else
{
auto device = Cvb::DeviceFactory::Open(Cvb::UI::QtToCvb(fileName), Cvb::AcquisitionStack::Vin);
// Connect the device with the ImageView
imageView_->Refresh(device->DeviceImage(), Cvb::UI::AutoRefresh::On);
// Create a stream handler
streamHandler_ = CustomStreamHandler::Create(device->Stream(), *this);
// Enable the grab check box for devices
grabCheckBox_->setEnabled(true);
}
}
catch (const std::exception& error)
{
QMessageBox::critical(this, "Error", QString(error.what()));
}
}
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
static std::unique_ptr< Image > Load(const String &fileName)
static std::unique_ptr< Recorder > Create(const String &path, Size2D< int > size, RecorderPixelFormat pixelFormat, const RecordingSettings &settings)
void SetUploadMode(Cvb::UI::UploadMode uploadMode)
Cvb::String QtToCvb(const QString text) noexcept
QString CvbToQt(const Cvb::String &text) noexcept
std::shared_ptr< Image > ImagePtr
String InstallPath()

main_widget.hpp:

#pragma once
#include <QWidget>
#include <QCheckBox>
#include <cvb/movie2/recorder.hpp>
#include <cvb/ui/image_view.hpp>
#include <cvb/async/single_stream_handler.hpp>
// The main widget
class MainWidget : public QWidget
{
Q_OBJECT
public:
explicit MainWidget();
virtual ~MainWidget() {}
private:
void Load(const QString& driver);
protected:
private:
Cvb::UI::ImageView* imageView_ = nullptr;
QLineEdit* movieFile_ = nullptr;
QCheckBox* grabCheckBox_ = nullptr;
// The custom stream handler to handle image processing while grabbing
class CustomStreamHandler :
{
public:
static std::unique_ptr<CustomStreamHandler> Create(const Cvb::StreamPtr& stream, MainWidget& mainWidget)
{
return std::unique_ptr<CustomStreamHandler>(new CustomStreamHandler(stream, mainWidget));
}
~CustomStreamHandler()
{
TryFinish();
}
private:
CustomStreamHandler(const Cvb::StreamPtr& stream, MainWidget& mainWidget)
: Cvb::SingleStreamHandler(stream)
, mainWidget_(mainWidget)
{}
void HandleAsyncStream(const Cvb::StreamPtr & stream) override
{
auto waitResult = stream->WaitFor(std::chrono::milliseconds(10000));
if (waitResult.Status != Cvb::WaitStatus::Ok)
return;
// Write the image to the recorder file
if (mainWidget_.recorder_)
mainWidget_.recorder_->Write(*waitResult.Image);
}
MainWidget& mainWidget_;
};
std::shared_ptr<CustomStreamHandler> streamHandler_;
};
std::shared_ptr< Recorder > RecorderPtr
std::shared_ptr< Stream > StreamPtr