add zoom control
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
VideoViewerWidget::VideoViewerWidget(QWidget *parent)
|
||||
: QWidget(parent), m_pipeline(nullptr), m_appSink(nullptr),
|
||||
m_busWatchId(0)
|
||||
m_busWatchId(0), m_zoomFactor(1.0)
|
||||
{
|
||||
// Register QImage as meta type for signal/slot across threads
|
||||
qRegisterMetaType<QImage>("QImage");
|
||||
@@ -38,12 +38,37 @@ void VideoViewerWidget::setupUI()
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(5);
|
||||
|
||||
// Video display - no GroupBox for maximum space
|
||||
m_videoDisplay = new QLabel(this);
|
||||
m_videoDisplay->setMinimumSize(640, 480);
|
||||
m_videoDisplay->setStyleSheet("background-color: black; border: 1px solid #666;");
|
||||
// Video display in scroll area for zoom support
|
||||
m_scrollArea = new QScrollArea(this);
|
||||
m_scrollArea->setWidgetResizable(false);
|
||||
m_scrollArea->setAlignment(Qt::AlignCenter);
|
||||
m_scrollArea->setStyleSheet("QScrollArea { background-color: black; border: 1px solid #666; }");
|
||||
|
||||
m_videoDisplay = new QLabel();
|
||||
m_videoDisplay->setMinimumSize(320, 240);
|
||||
m_videoDisplay->setStyleSheet("background-color: black;");
|
||||
m_videoDisplay->setAlignment(Qt::AlignCenter);
|
||||
m_videoDisplay->setScaledContents(false); // Disable for better aspect ratio control
|
||||
m_videoDisplay->setScaledContents(false);
|
||||
|
||||
m_scrollArea->setWidget(m_videoDisplay);
|
||||
|
||||
// Zoom control
|
||||
QHBoxLayout* zoomLayout = new QHBoxLayout();
|
||||
zoomLayout->addWidget(new QLabel("Zoom:", this));
|
||||
|
||||
m_zoomSlider = new QSlider(Qt::Horizontal, this);
|
||||
m_zoomSlider->setMinimum(50); // 50%
|
||||
m_zoomSlider->setMaximum(200); // 200%
|
||||
m_zoomSlider->setValue(100); // 100% default
|
||||
m_zoomSlider->setTickPosition(QSlider::TicksBelow);
|
||||
m_zoomSlider->setTickInterval(25);
|
||||
connect(m_zoomSlider, &QSlider::valueChanged, this, &VideoViewerWidget::onZoomChanged);
|
||||
|
||||
m_zoomLabel = new QLabel("100%", this);
|
||||
m_zoomLabel->setMinimumWidth(50);
|
||||
|
||||
zoomLayout->addWidget(m_zoomSlider);
|
||||
zoomLayout->addWidget(m_zoomLabel);
|
||||
|
||||
// Controls
|
||||
QGroupBox* controlGroup = new QGroupBox("Viewer Controls", this);
|
||||
@@ -91,8 +116,9 @@ void VideoViewerWidget::setupUI()
|
||||
controlLayout->addWidget(m_statusLabel);
|
||||
controlGroup->setLayout(controlLayout);
|
||||
|
||||
// Add to main layout: video takes most space, controls at bottom
|
||||
mainLayout->addWidget(m_videoDisplay, 1);
|
||||
// Add to main layout: video takes most space, zoom control, then viewer controls at bottom
|
||||
mainLayout->addWidget(m_scrollArea, 1);
|
||||
mainLayout->addLayout(zoomLayout);
|
||||
mainLayout->addWidget(controlGroup);
|
||||
|
||||
setLayout(mainLayout);
|
||||
@@ -220,9 +246,10 @@ void VideoViewerWidget::stopPipeline()
|
||||
m_busWatchId = 0;
|
||||
}
|
||||
|
||||
// Clear video display
|
||||
// Clear video display and current frame
|
||||
m_videoDisplay->clear();
|
||||
m_videoDisplay->setText("");
|
||||
m_currentFrame = QImage();
|
||||
|
||||
m_statusLabel->setText("Status: Stopped");
|
||||
m_statusLabel->setStyleSheet("QLabel { background-color: #f0f0f0; padding: 5px; border-radius: 3px; }");
|
||||
@@ -322,8 +349,28 @@ void VideoViewerWidget::onSourceTypeChanged(int index)
|
||||
m_portEdit->setEnabled(needsNetwork);
|
||||
}
|
||||
|
||||
void VideoViewerWidget::onZoomChanged(int value)
|
||||
{
|
||||
m_zoomFactor = value / 100.0;
|
||||
m_zoomLabel->setText(QString("%1%").arg(value));
|
||||
|
||||
// Re-display the current frame with new zoom factor
|
||||
if (!m_currentFrame.isNull()) {
|
||||
displayFrame(m_currentFrame);
|
||||
}
|
||||
}
|
||||
|
||||
GstFlowReturn VideoViewerWidget::newSampleCallback(GstAppSink* appsink, gpointer user_data)
|
||||
{
|
||||
static int callbackCount = 0;
|
||||
callbackCount++;
|
||||
|
||||
if (callbackCount == 1) {
|
||||
qDebug() << "[VideoViewer] Callback: First sample callback!";
|
||||
} else if (callbackCount % 30 == 0) {
|
||||
qDebug() << "[VideoViewer] Callback: Samples received:" << callbackCount;
|
||||
}
|
||||
|
||||
VideoViewerWidget* viewer = static_cast<VideoViewerWidget*>(user_data);
|
||||
if (!viewer) {
|
||||
qDebug() << "[VideoViewer] Callback: viewer is null";
|
||||
@@ -405,15 +452,44 @@ void VideoViewerWidget::displayFrame(const QImage& frame)
|
||||
}
|
||||
|
||||
static bool firstFrame = true;
|
||||
static int frameCount = 0;
|
||||
frameCount++;
|
||||
|
||||
bool debugThisFrame = firstFrame || (frameCount % 30 == 0);
|
||||
|
||||
if (firstFrame) {
|
||||
qDebug() << "[VideoViewer] First frame received! Size:" << frame.width() << "x" << frame.height();
|
||||
qDebug() << "[VideoViewer] First frame received! Size:" << frame.width() << "x" << frame.height()
|
||||
<< "Format:" << frame.format();
|
||||
firstFrame = false;
|
||||
} else if (frameCount % 30 == 0) {
|
||||
qDebug() << "[VideoViewer] Frames received:" << frameCount;
|
||||
}
|
||||
|
||||
// Convert QImage to QPixmap and scale to fit label while keeping aspect ratio
|
||||
// Store current frame for zoom changes
|
||||
m_currentFrame = frame;
|
||||
|
||||
// Convert QImage to QPixmap
|
||||
QPixmap pixmap = QPixmap::fromImage(frame);
|
||||
QPixmap scaledPixmap = pixmap.scaled(m_videoDisplay->size(),
|
||||
if (pixmap.isNull()) {
|
||||
qDebug() << "[VideoViewer] ERROR: Pixmap conversion failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate target size with zoom factor
|
||||
QSize targetSize = frame.size() * m_zoomFactor;
|
||||
|
||||
// Scale pixmap with zoom factor
|
||||
QPixmap scaledPixmap = pixmap.scaled(targetSize,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
|
||||
if (debugThisFrame) {
|
||||
qDebug() << "[VideoViewer] Target size:" << targetSize << "Zoom:" << m_zoomFactor
|
||||
<< "Scaled pixmap:" << scaledPixmap.size();
|
||||
}
|
||||
|
||||
// Update the label size to match the scaled pixmap
|
||||
m_videoDisplay->setPixmap(scaledPixmap);
|
||||
m_videoDisplay->resize(scaledPixmap.size());
|
||||
m_videoDisplay->update();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user