Selecting a part of image



  • I need to select a part of image, and do something on this. What I should use? Example scenario:

    1. Load a picture to QLabel(or other class? QLabel will be good for this?).
    2. Select part of picture.
    3. Selected part will be saved to file and maybe will be scaled or rotated also.

    I need a hint how to do this.



  • You got it right, QLabel has both picture and pixmap properties and you can use it easily to show image on screen.

    Selecting part of picture would take a bit more time, as you probably want to draw selecting rectangle, and that would take care of click and release events on QLabel and changing copy of image (drawing selecting rectangle), and having two states - nothing selected, something selected.

    Third useful class (first is QLabel, second QPicture/QPixmap) would be QMouseEvent, and its pos() method.

    When you figure out how to do selection, saving/manipulating selection will be easy.

    That would be a hint, rest is putting it all together without syntax errors and functional as planned ;)



  • Today or tomorrow I will start doing it - thanks for hints.



  • Also interesting to look at: [[doc:QRubberBand]]



  • Hi, my name is Santa, and I decided to help you!

    The header is

    @
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QLabel>
    #include <QMenu>

    class Widget : public QLabel
    {
    Q_OBJECT

    public:
    Widget(QWidget *parent = 0);
    ~Widget();
    protected:
    void paintEvent(QPaintEvent *e);
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
    private:

    bool selectionStarted;
    QRect selectionRect;
    QMenu contextMenu;
    

    private slots:
    void saveSlot();

    };

    #endif // WIDGET_H

    @

    and then the cpp is

    @
    #include "widget.h"
    #include <QPainter>
    #include <QMouseEvent>
    #include <QDebug>
    #include <QAction>
    #include <QFileDialog>

    Widget::Widget(QWidget *parent)
    : QLabel(parent)
    {
    selectionStarted=false;

    QAction *saveAction=contextMenu.addAction("Save");
    
    connect(saveAction,SIGNAL(triggered()),this,SLOT(saveSlot()));
    

    }

    Widget::~Widget()
    {

    }

    void Widget::paintEvent(QPaintEvent *e)
    {
    QPainter painter(this);
    QLabel::paintEvent(e);
    painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
    painter.setBrush(QBrush(QColor(255,255,255,120)));

    painter.drawRect(selectionRect);
    

    }

    void Widget::mousePressEvent(QMouseEvent *e)
    {
    if (e->button()==Qt::RightButton)
    {
    if (selectionRect.contains(e->pos())) contextMenu.exec(this->mapToGlobal(e->pos()));
    }
    else
    {
    selectionStarted=true;
    selectionRect.setTopLeft(e->pos());
    selectionRect.setBottomRight(e->pos());
    }

    }

    void Widget::mouseMoveEvent(QMouseEvent *e)
    {
    if (selectionStarted)
    {
    selectionRect.setBottomRight(e->pos());
    repaint();
    }
    }

    void Widget::mouseReleaseEvent(QMouseEvent *e)
    {
    selectionStarted=false;
    }

    void Widget::saveSlot()
    {
    QString fileName = QFileDialog::getSaveFileName(this, QObject::tr("Save File"),
    "/home",
    QObject::tr("Images (*.jpg)"));
    this->pixmap()->copy(selectionRect).save(fileName);
    }

    @

    and the main is

    @
    #include <QtGui/QApplication>
    #include "widget.h"
    #include <QFileDialog>
    #include <QPixmap>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;

    QString fileName = QFileDialog::getOpenFileName(&w, QObject::tr("Open File"),
                                                    "/home",
                                                    QObject::tr("Images (*.png *.xpm *.jpg)"));
    QPixmap pixmap(fileName);
    w.setPixmap(fileName);
    w.resize(pixmap.size());
    w.show();
    
    return a.exec&#40;&#41;;
    

    }

    @

    P.S. oh, sorry, not Santa, SATAN! because you could easily do it yourself and now you're going to learn nothing! HO HO HO



  • Thanks for hint and the code ... it is help full .



  • Thanks for providing a complete solution.

    Your program is giving a segmentation fault at libe 26/27 of widget.cpp.

    @
    QLabel::paintEvent(e);
    painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
    @



  • I had the same problem and used your solution. One minor change :

    You need to call the "Superclass" Paint event before opening the new QPainter!
    @
    QLabel::paintEvent(e);
    QPainter painter(this);
    painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
    painter.setBrush(QBrush(QColor(255,255,255,120)));
    painter.drawRect(selectionRect);
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.