PDA

View Full Version : Visualize an Image and copy a portion



Polielia
27th February 2017, 14:33
Hi, my goal is to visualize an image (e.g. in a QLabel), allow the use to select a portion of this image and visualize this portion in another QLabel. I have written the code, but I have a problem, the portion of image that I visualize is different from the selected part
CODE CPP



void Button1_nyq::on_selectimage_nyq_Hom_clicked()
{

Imagename = QFileDialog::getOpenFileName(this,tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg)")); //apro l'immagine
//visualize the image in the first Label
QPixmap image(Imagename);
ui->ImageDisplay->setPixmap(image); //ImageDisplay is the name of QLabel
}
int count_selection=0; ///when it is not 0 it mean that the user want to make another selection and I hide the previous


void Button1_nyq::mousePressEvent(QMouseEvent *e)
{
if(count_selection!=0)
rubberBand->hide();
point1 = e->pos();
rubberBand = new QRubberBand(QRubberBand::Rectangle,this );
}

void Button1_nyq::mouseMoveEvent(QMouseEvent *e)
{
rubberBand->show();
rubberBand->setGeometry(QRect(point1,e->pos()));
}

void Button1_nyq::mouseReleaseEvent(QMouseEvent *e)
{
count_selection++;
QRect rect; //selection rectangle
rect.setTopLeft(point1);
rect.setBottomRight(e->pos()));
QPixmap image(rect.size());
ui->ImageDisplay->render(&image,QPoint(0,0),QRegion(rect)); //copy the selected part into "image"
ui->label_image_selected->setPixmap(image); //show "image" in the second QLabel


the actual results are:
Real image
http://imgur.com/9f6e0D3
Selected image
http://imgur.com/lysvM0q
Result
http://imgur.com/s0FydTc

How can I fix it?

Santosh Reddy
28th February 2017, 05:00
Some reason I cannot open the images, but any way here is simple working code


class ImageCopier : public QLabel
{
Q_OBJECT
public:
ImageCopier(QWidget * parent = 0)
: QLabel(parent)
, mRubberBand(new QRubberBand(QRubberBand::Rectangle, this))
{
setPixmap(QPixmap(QFileDialog::getOpenFileName(thi s, tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg;*.png)"))));
}

signals:
void selectionChanged(const QPixmap & image);

protected:
void mousePressEvent(QMouseEvent * event)
{
emit selectionChanged(QPixmap());

mStart = event->pos();
mRubberBand->setGeometry(QRect(mStart, QSize()));
mRubberBand->show();
}

void mouseMoveEvent(QMouseEvent * event)
{
mRubberBand->setGeometry(QRect(mStart, event->pos()).normalized());
}

void mouseReleaseEvent(QMouseEvent * event)
{
mRubberBand->setGeometry(QRect(mStart, event->pos()).normalized());
mRubberBand->hide();
emit selectionChanged(grab(mRubberBand->geometry()));
}

private:
QRubberBand * mRubberBand;
QPoint mStart;
};

Polielia
28th February 2017, 09:33
thanks, I have update my code and now works perfectly!
My final solution is:


void Button1_nyq::on_selectimage_nyq_Hom_clicked()
{

Imagename = QFileDialog::getOpenFileName(this,tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg)")); //apro l'immagine
//visualize the image in the first Label
QPixmap image(Imagename);
ui->ImageDisplay->setPixmap(image); //ImageDisplay is the name of QLabel
}

void Button1_nyq::mousePressEvent(QMouseEvent *e)
{

point1 = e->pos();
rubberBand = new QRubberBand(QRubberBand::Rectangle,this );
}

void Button1_nyq::mouseMoveEvent(QMouseEvent *e)
{
rubberBand->show();
rubberBand->setGeometry(QRect(point1,e->pos()));
}

void Button1_nyq::mouseReleaseEvent(QMouseEvent *e)
{
rubberband->hide();
QRect rect; //selection rectangle
rect.setTopLeft(point1);
rect.setBottomRight(e->pos()));

QPixmap image(rect.size());
image = grab(rubberband->geometry()); //copy the selected part
ui->label_image_selected->setPixmap(image); //show "image" in the second QLabel


Added after 11 minutes:

One more question, if now I want to maintain the rubberband on the screen? because when I hide the Rubberband it all ok, but if I dont hide it in the second label I have the portion of image selected but also the color of the rubberband.
So I want keep the rubberband in the first Label, but hide it in the second (where I show the result)... Or I can change the color of the rubberband, maybe I can maintain only the border and have white in the middle, it is possible to do?

d_stranz
28th February 2017, 19:01
In the first image, hide the rubberband, copy the selected portion, then show the rubberband again. When the rubberband is visible, it is part of the image on the first label, so copying that part will copy everything including the rubberband.

A more common way to do rubberbanding which avoids this problem is to use an overlay widget - a widget with the same size as your label and positioned on top of it, but with a transparent background. You use that widget to draw your rubberband, while the real label underneath that isn't changed at all. Once you have used the rubber band in the overlay widget to select the region, you use the same coordinates to select that part of the label widget. Since the rubber band is drawn on the overlay and not on the label, it doesn't appear in the bits you copy to the new label. Google for "qt overlay widget".

Polielia
1st March 2017, 11:30
In the first image, hide the rubberband, copy the selected portion, then show the rubberband again. When the rubberband is visible, it is part of the image on the first label, so copying that part will copy everything including the rubberband.



thanks, i have used this solution and works fine ;)