Subversion Repositories seema-scanner

Rev

Rev 220 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "SMVideoZoomWidget.h"

#include "cvtools.h"

#include <QScrollBar>
#include <QMenu>

SMVideoZoomWidget::SMVideoZoomWidget(QWidget *parent) : QGraphicsView(parent)
{
    scene = new QGraphicsScene(this);
    item = new QGraphicsPixmapItem;

    scene->addItem(item);

    setScene(scene);

    // Causes weird scroll bars
    //this->setStyleSheet("background: transparent");

    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));

}


static QImage cvMat2qImage(cv::Mat mat){

    // 8-bits unsigned, raw bayer image
    if(mat.type()==CV_8UC1) {
        cv::Mat rgb;
        cv::cvtColor(mat, rgb, CV_BayerBG2RGB);
        QImage img((const uchar*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888);
        img = img.copy();
        return img;
    // 8-bit unsigned rgb image
    } else if(mat.type()==CV_8UC3) {
        // Copy input Mat
        QImage img((const uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return img;
    // 16-bit unsigned, raw bayer image
    } else if(mat.type()==CV_16UC1) {
        cv::Mat mat8bit = mat.clone();
        cvtools::rshift(mat8bit, 8);
        mat8bit.convertTo(mat8bit, CV_8UC1);
        cv::Mat rgb;
        cv::cvtColor(mat8bit, rgb, CV_BayerBG2RGB);
        QImage img((const uchar*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888);
        img = img.copy();
        return img;
    // 16-bit unsigned rgb image
    } else if(mat.type()==CV_16UC3) {
        mat.convertTo(mat, CV_8UC3, 1.0/256.0);
        return cvMat2qImage(mat);
    // 32bit floating point gray-scale image
    } else if(mat.type()==CV_32FC1) {
        cv::Mat rgb(mat.size(), CV_32FC3);
        cv::cvtColor(mat, rgb, cv::COLOR_GRAY2RGB);
        QImage img((const uchar*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB32);
        img = img.copy();
        return img;
    } else {
        std::cerr << "SMVideoWidget: cv::Mat could not be converted to QImage!";
        return QImage();
    }

    // 8-bit unsigned gray-scale image
//    } else if(mat.type()==CV_8UC1) {
//        // Set the color table (used to tranMVate colour indexes to qRgb values)
//        QVector<QRgb> colorTable;
//        for (int i=0; i<256; i++)
//            colorTable.push_back(qRgb(i,i,i));
//        // Copy input Mat
//        QImage img((const uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
//        img.setColorTable(colorTable);
//        return img;
}


void SMVideoZoomWidget::showImageCV(cv::Mat image){

    QImage qimage = cvMat2qImage(image);

    // If first ever camera image, fit in view
    if(item->pixmap().isNull()){
        item->setPixmap(QPixmap::fromImage(qimage));
        this->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
    } else {
        item->setPixmap(QPixmap::fromImage(qimage));
    }

}


void SMVideoZoomWidget::mousePressEvent(QMouseEvent *event)
{
//    // Drag mode : change the cursor's shape
//    if (event->button() == Qt::LeftButton)
//        this->setDragMode(QGraphicsView::ScrollHandDrag);

    QGraphicsView::mousePressEvent(event);
}

// Called when a mouse button is pressed
void SMVideoZoomWidget::mouseReleaseEvent(QMouseEvent *event)
{
//    // Exit drag mode : change the cursor's shape
//    if (event->button() == Qt::LeftButton) this->setDragMode(QGraphicsView::NoDrag);
    QGraphicsView::mouseReleaseEvent(event);
}


void SMVideoZoomWidget::wheelEvent(QWheelEvent *event)
{
    // When zooming, the view stay centered over the mouse
    this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

    double factor = 1.3;
    if(event->delta() > 0)
        // Zoom in
        scale(factor, factor);
    else
        // Zooming out
        scale(1.0 / factor, 1.0 / factor);

    // The event is processed
    event->accept();

    if(this->horizontalScrollBar()->isVisible() || this->verticalScrollBar()->isVisible())
        this->setDragMode(QGraphicsView::ScrollHandDrag);
    else
        this->setDragMode(QGraphicsView::NoDrag);
}

// Overloaded functionthat catch the resize event
void SMVideoZoomWidget::resizeEvent(QResizeEvent *event)
{
//    // First call, the scene is created
//    if(event->oldSize().width() == -1 || event->oldSize().height() == -1) return;

//    // Get the previous rectangle of the scene in the viewport
//    QPointF P1=mapToScene(QPoint(0,0));
//    QPointF P2=mapToScene(QPoint(event->oldSize().width(),event->oldSize().height()));

//    // Stretch the rectangle around the scene
//    if (P1.x()<0) P1.setX(0);
//    if (P1.y()<0) P1.setY(0);
//    if (P2.x()>scene->width()) P2.setX(scene->width());
//    if (P2.y()>scene->height()) P2.setY(scene->height());

//    // Fit the previous area in the scene
//    this->fitInView(QRect(P1.toPoint(),P2.toPoint()),Qt::KeepAspectRatio);

    if(this->horizontalScrollBar()->isVisible() || this->verticalScrollBar()->isVisible())
        this->setDragMode(QGraphicsView::ScrollHandDrag);
    else
        this->setDragMode(QGraphicsView::NoDrag);

    QGraphicsView::resizeEvent(event);
}

// Display contextual menu
void SMVideoZoomWidget::showContextMenu(const QPoint &pos)
{
    // Get the mouse position in the scene
    QPoint globalPos = mapToGlobal(pos);
    // Create the menu and add action
    QMenu contextMenu;
    contextMenu.addAction("Reset view", this, SLOT(fitImage()));
    // Display the menu
    contextMenu.exec(globalPos);
}

void SMVideoZoomWidget::fitImage(){

    // Turn scroll bars off temporarily to get correct widget size
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    this->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);

    // Restore scroll bar policy
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

SMVideoZoomWidget::~SMVideoZoomWidget(){
    delete scene;
    delete item;
}