/*
- This file is one part of two, that together make
- QOpenCamWidget, a Qt 4 widget that displays video input
- from a webcam, along with an optional snapshot button.
+ This file is one part of two, that together make QOpenCamWidget,
+ a Qt 4 widget that displays video input from a webcam.
Copyright (C) 2009 Jon Langseth
* \code
* QOpenCamWidget *cw = new QOpenCamWidget(this);
* if ( cw->grabCapture(-1) ) {
- * cw->setSnapshotVisible(true);
* cw->startCapture();
* }
* connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));
+ *
+ * QPushButton *trigger = new QPushButton(this);
+ * trigger->setText("Take picture");
+ * connect( trigger, SIGNAL(clicked()), cw, SLOT(startSnap()));
+ *
* \endcode
*
* \param *parent The parent widget containing this widget, defaults to NULL.
QOpenCamWidget::QOpenCamWidget(QWidget *parent)
: QWidget(parent)
{
- // private CvCapture *nextFrame from class definition
+ // Setting sane default values (i.e. NULL) for
+ // private CvCapture *nextFrame and
+ // private QTimer *frametimer from class definition
nextFrame = NULL;
- // private QTimer *frametimer from class definition
frametimer = NULL;
- // private QVBoxLayout *layout from class definition
- layout = new QVBoxLayout(this);
-
- // private QLabel *canvas from class definition
- canvas = new QLabel(this);
- canvas->setMinimumSize(200, 100);
- canvas->setAlignment(Qt::AlignCenter);
-
- // private QPushButton *trigger from class definition
- trigger = new QPushButton(this);
- trigger->setText("Take picture");
- trigger->setEnabled(false);
- trigger->hide();
-
- // private bool trigger_active from class definition
- trigger_active = false;
-
- layout->addWidget(canvas);
- this->setLayout(layout);
}
QOpenCamWidget::~QOpenCamWidget(void)
{
cvReleaseCapture( &capture );
- delete canvas;
- delete trigger;
}
// ------------------------------------------------------------- //
// Public methods (not signals/slots)
// ------------------------------------------------------------- //
-/*!
- * \brief Changes the visibility of the optional built-in "Take snapshot" button.
- *
- * The widget contains a push-button that optionally can be displayed. When
- * visible, this button is located at the bottom of the widget, and causes
- * the SLOT QOpenCamWidget::startSnap to be triggered when clicked.
- *
- * \param visible True makes the button display, and trigger,
- * false turns the feature off. False, i.e. no button, is default.
- *
- **/
-void
-QOpenCamWidget::setSnapshotVisible(bool visible)
-{
- // Checking both parameter and private "sanity" variable,
- // as a sanity- and error-control
- if ( visible && !trigger_active )
- {
- connect( trigger, SIGNAL(clicked()), this, SLOT(startSnap()));
- layout->addWidget(trigger);
- trigger->show();
- trigger_active = true;
- }
- if ( !visible && trigger_active )
- {
- layout->removeWidget(trigger);
- disconnect( trigger, SIGNAL(clicked()), 0, 0 );
- trigger->hide();
- trigger_active = false;
- }
-}
/*!
* \brief A paint event is a request to repaint all or part of a widget.
*
if ( nextFrame )
{
- // Using this objects painter to draw the image
- // causes a cute, but not desired effect..
- //paint->drawImage(event->rect(), *nextFrame);
-
- // Until I find a better solution on how to do the
- // redraw of the image, setPixmap on the canvas
- // does do the job. This may cause a performance
- // penalty though, and is considered a FIXME
- // Another drawback is that the widget does not resize..
- canvas->setPixmap( QPixmap::fromImage(*nextFrame) );
+ // To make the widget as blazingly fast as possible
+ // we output the last captured frame direclty onto
+ // the widget area.
+ paint->drawImage(event->rect(), *nextFrame);
}
else
{
- canvas->setText("No data, check/test camera");
+ paint->drawText(event->rect(),"No data, check/test camera");
}
paint->end();
+ // Clean up..
+ delete(paint);
}
IplImage *image = cvRetrieveFrame(capture);
QSize t_size = QSize(image->width,image->height);
- qDebug() << "Device image format: " << image->width << "x" << image->height;
- canvas->setMinimumSize(t_size);
- canvas->setMaximumSize(t_size);
+ this->setMinimumSize(t_size);
+ this->setMaximumSize(t_size);
return true;
}
QOpenCamWidget::startCapture(void)
{
frametimer = new QTimer(this);
- frametimer->start(70);
+ frametimer->start(50);
connect(frametimer,SIGNAL(timeout()), this,SLOT(grabFrame()));
- trigger->setEnabled(true);
}
/*!
*
**/
QImage*
-QOpenCamWidget::Ipl2QImage(const IplImage *img)
+QOpenCamWidget::Ipl2QImage(IplImage *img)
{
- IplImage *tmp=cvCloneImage(img);
- cvConvertImage(img,tmp, CV_CVTIMG_SWAP_RB );
- QImage * qimage = new QImage(reinterpret_cast<uchar*>(tmp->imageData),
- tmp->width,
- tmp->height,
- 3* tmp->width,
- QImage::Format_RGB888);
+ cvConvertImage(img,img, CV_CVTIMG_SWAP_RB);
+ QImage * qimage = new QImage(
+ reinterpret_cast<uchar*>(img->imageData),
+ img->width, img->height,
+ 3* img->width, QImage::Format_RGB888);
return qimage;
}
**/
void QOpenCamWidget::grabFrame(void)
{
- if ( !capture )
- {
- qDebug() << "Capture device not ready!";
- return;
- }
+ if ( !capture ) { qDebug() << "Capture device not ready!"; return; }
cvGrabFrame(capture);
IplImage *iplimage = cvRetrieveFrame(capture);
-
if (iplimage)
{
nextFrame = Ipl2QImage(iplimage);
{
nextFrame = NULL;
}
+
update();
}
* stopped, and the last displayed frame is "captured", and made
* available through the emitting of the class imageReady SIGNAL.
*
- * With the "Take snapshot" button visible (setSnapshotVisible(true)),
- * this SLOT is triggered when the user clicks on the trigger button.
- * If you do not wish to use the internal trigger button, you
- * will have to add a different mechanism to trigger this SLOT.
- *
* It is possible, though I would not recommend, to use repeated
* triggering of this slot to do repeated frame-capture, and thus
* make a form of "Animation" or "Video" capture.
if (frametimer->isActive())
{
frametimer->stop();
- qDebug() << "SNAP!";
-
emit imageReady(QImage(*nextFrame));
frametimer->start();
}