Visualizzare un'immagine e copiarne una porzione
-
Salve, come da titolo il mio obiettivo è quello di visualizzare un'immagine (io l'ho messa in un QLabel), dare la possibilità all'utente di selezionarne una parte ( disegnando un rettangolo) e visualizzare la porzione selezionata in un altro QLabel.
Il problema è che quando vado a visualizzare la selezione non ottengo la porzione di immagine selezionata, ma un altro pezzo di immagine. Ecco il mio codice:
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 //mostro l'immagine QPixmap image(Imagename); ui->ImageDisplay->setPixmap(image); //ImageDisplay è il nome del QLabel } int count_selection=0; //quando è diverso da 0 faccio sparire vuol dire che l'utente vuole disegnare un altro rettangolo, quindi nascondo il precedente 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(Imagename); QPixmap a = image.copy(rect); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(a); //mostro l'immagine nel secondo QLabel } }
.h
#ifndef BUTTON1_NYQ_H #define BUTTON1_NYQ_H #include <QDialog> #include <qrubberband.h> namespace Ui { class Button1_nyq; } class Button1_nyq : public QDialog { Q_OBJECT public: explicit Button1_nyq(QWidget *parent = 0); ~Button1_nyq(); private slots: void on_selectimage_nyq_Hom_clicked(); void on_SAVE_clicked(); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); private: Ui::Button1_nyq *ui; QRubberBand *rubberBand; }; #endif // BUTTON1_NYQ_H
Eglish version: https://forum.qt.io/topic/76667/visualize-an-image-and-copy-a-portion
cosa sto sbagliando? :O -
il problema e' in
e->pos()
quella e' relativa aButton1_nyq
non alla labelusa
e->globalPos()
e usaQLabel::mapFromGloabal
per convertirli in coordinate dell'immagine@VRonin Grazie per la risposta, ma non sono riuscito a trovare info in rete, quindi ho improvvisato e ho ancora dei problemi, ho modificato cosi:
void Button1_nyq::on_selectimage_nyq_Hom_clicked() { Imagename = QFileDialog::getOpenFileName(this,tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg)")); //apro l'immagine //mostro l'immagine QPixmap image(Imagename); QPoint zero(0,0); ui->ImageDisplay->mapFromGlobal(zero); //mapFromGlobal mi chiede un QPoint come parametro, è giusto cosi? ui->ImageDisplay->setPixmap(image); //ImageDisplay è il nome del QLabel } int count_selection=0; //quando è diverso da 0 faccio sparire vuol dire che l'utente vuole disegnare un altro rettangolo, quindi nascondo il precedente void Button1_nyq::mousePressEvent(QMouseEvent *e) { if(count_selection!=0) rubberBand->hide(); point1 = e->globalPos(); rubberBand = new QRubberBand(QRubberBand::Rectangle,this ); } void Button1_nyq::mouseMoveEvent(QMouseEvent *e) { rubberBand->show(); rubberBand->setGeometry(QRect(point1,e->globalPos())); } void Button1_nyq::mouseReleaseEvent(QMouseEvent *e) { count_selection++; QRect rect; //selection rectangle rect.setTopLeft(point1); rect.setBottomRight(e->globalPos()); QPixmap image(Imagename); QPixmap a = image.copy(rect); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(a); //mostro l'immagine nel secondo QLabel
il fatto è che ora il rettangolo di selezione non viene disegnato dal punto del primo click ma altrove
-
QPoint zero(0,0);
ui->ImageDisplay->mapFromGlobal(zero); //mapFromGlobal mi chiede un QPoint come parametro, è giusto cosi?no, mapFromGlobal deve essere usato nel rect, non qui
QRect rect; //selection rectangle rect.setTopLeft(ui->ImageDisplay->mapFromGlobal(point1)); rect.setBottomRight(ui->ImageDisplay->mapFromGlobal(e->globalPos()));
-
QPoint zero(0,0);
ui->ImageDisplay->mapFromGlobal(zero); //mapFromGlobal mi chiede un QPoint come parametro, è giusto cosi?no, mapFromGlobal deve essere usato nel rect, non qui
QRect rect; //selection rectangle rect.setTopLeft(ui->ImageDisplay->mapFromGlobal(point1)); rect.setBottomRight(ui->ImageDisplay->mapFromGlobal(e->globalPos()));
@VRonin ok quindi riscrivendo il codice cosi:
void Button1_nyq::on_selectimage_nyq_Hom_clicked() { Imagename = QFileDialog::getOpenFileName(this,tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg)")); //apro l'immagine //mostro l'immagine QPixmap image(Imagename); ui->ImageDisplay->setPixmap(image); //ImageDisplay è il nome del QLabel } int count_selection=0; //quando è diverso da 0 faccio sparire vuol dire che l'utente vuole disegnare un altro rettangolo, quindi nascondo il precedente void Button1_nyq::mousePressEvent(QMouseEvent *e) { if(count_selection!=0) rubberBand->hide(); point1 = e->globalPos(); rubberBand = new QRubberBand(QRubberBand::Rectangle,this ); } void Button1_nyq::mouseMoveEvent(QMouseEvent *e) { rubberBand->show(); rubberBand->setGeometry(QRect(point1,e->globalPos())); } void Button1_nyq::mouseReleaseEvent(QMouseEvent *e) { count_selection++; QRect rect; //selection rectangle rect.setTopLeft(ui->ImageDisplay->mapFromGlobal(point1)); rect.setBottomRight(ui->ImageDisplay->mapFromGlobal(e->globalPos())); QPixmap image(Imagename); QPixmap a = image.copy(rect); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(a); //mostro l'immagine nel secondo QLabel
il risultato non cambia, il rettangolo viene ancora disegnato in un punto iniziale che non è quello di click
-
prova a sostituire
QPixmap a = image.copy(rect);
conui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect));
@VRonin said in Visualizzare un'immagine e copiarne una porzione:
ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect));
se ho scritto giusto
QPixmap a = ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect));
ho il seguente errore
...\gui\button1_nyq.cpp:224: error: conversion from 'void' to non-scalar type 'QPixmap' requested QPixmap a = ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect));//copy the selected image in a ^
-
togli
QPixmap a =
QPixmap image(rect.size()); ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect)); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(a); //mostro l'immagine nel secondo QLabel
ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect)); ui->label_image_selected->setPixmap(a); //show the image selected
cosi mi dice
...\gui\button1_nyq.cpp:224: error: no matching function for call to 'QLabel::render(int*, QPoint, QRegion)' ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect));//copy the selected image in a ^ ^
e per la seconda riga
...\gui\button1_nyq.cpp:227: error: no matching function for call to 'QLabel::setPixmap(int&)' ui->label_image_selected->setPixmap(a); //show the image selected
-
togli
QPixmap a =
QPixmap image(rect.size()); ui->ImageDisplay->render(&a,QPoint(0,0),QRegion(rect)); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(a); //mostro l'immagine nel secondo QLabel
@VRonin ok scusa colpa mia, cambiando quella riga mi sono dimenticato che a era un intero usato da un'altra parte
quindi:QPixmap image(rect.size()); ui->ImageDisplay->render(&k,QPoint(0,0),QRegion(rect)); //copio l'immagine selezionata in a ui->label_image_selected->setPixmap(k); //mostro l'immagine nel secondo QLabel
ora però mi da giustamente errore su k, dicendo che non è dichiarato
edit:
provando a dichiarare k come un QPixmap: il rettangolo è sempre disegnato in posizione diversa da quella del primo click, non viene visualizzato nulla nel secondo label -
-
Che casino che abbiamo fatto. ok,
QPixmap image(rect.size()); ui->ImageDisplay->render(&image,QPoint(0,0),QRegion(rect)); //copio l'immagine selezionata in image ui->label_image_selected->setPixmap(image); //mostro l'immagine nel secondo QLabel
@VRonin
ok allora il codice che ho ora èvoid Button1_nyq::on_selectimage_nyq_Hom_clicked() { Imagename = QFileDialog::getOpenFileName(this,tr("Open Image for Nyquist Test"), "", tr("Images (*.jpg)")); //apro l'immagine //mostro l'immagine QPixmap image(Imagename); ui->ImageDisplay->setPixmap(image); //ImageDisplay è il nome del QLabel } int count_selection=0; //quando è diverso da 0 faccio sparire vuol dire che l'utente vuole disegnare un altro rettangolo, quindi nascondo il precedente 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)); //copio l'immagine selezionata in image ui->label_image_selected->setPixmap(image); //mostro l'immagine nel secondo QLabel
cosi,usando pos, al posto di globalpos il rettangolo viene visualizzato correttamente e l'immagine copiata è più precisa rispetto a prima, nel senso che prima veniva traslata su 2 dimesioni, ora invece viene visualizzata un'immagine di poco traslata solo sull'asse x. Hai idee per questo?
usando globalpos non sono riuscito a disegnare il rettangolo correttamenteQuesto è il risultato che ottengo ora:
Real image
http://imgur.com/9f6e0D3
Selected image
http://imgur.com/lysvM0q
Result
http://imgur.com/s0FydTc -
Ho risolto il problema, questa è la mia soluzione per chi dovvesse avere lo stesso inconveniente
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
-
La via giusta comunque sarebbe usare il framework QGraphicView o la moderna alternativa in Qt Quick. QLabel e' progettata per essere un display di scritte o immagini, non per iteragirvi
-
La via giusta comunque sarebbe usare il framework QGraphicView o la moderna alternativa in Qt Quick. QLabel e' progettata per essere un display di scritte o immagini, non per iteragirvi