/*********************************************************************/ /* */ /* Copyright 2022-2023 Rémi Synave - remi.synave@univ-littoral.fr */ /* */ /* This file is part of DSL. */ /* This software uses Qt to build the Graphical User Interface */ /* https://www.qt.io/ */ /* */ /* DSL is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published */ /* by the Free Software Foundation, either version 3 of the License, */ /* or (at your option) any later version. */ /* */ /* DSL is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with DSL. If not, see . */ /* */ /*********************************************************************/ #include #include #include #include #include #include #include #include #include "WorkArea.hpp" WorkArea::WorkArea (int screenSizeX, int screenSizeY, QWidget * parent): QWidget(parent) { this->screenSizeX = screenSizeX; this->screenSizeY = screenSizeY; readOnly = false; modificationInProgress = false; img = NULL; resizeFactor = 1; indexPointClicked = -1; maxLines = 0; } WorkArea::WorkArea (int screenSizeX, int screenSizeY, const std::string & filename, QWidget * parent):QWidget(parent) { this->screenSizeX = screenSizeX; this->screenSizeY = screenSizeY; readOnly = false; modificationInProgress = false; img = NULL; resizeFactor = 1; indexPointClicked = -1; maxLines = 0; loadImage(filename); } WorkArea::WorkArea (int screenSizeX, int screenSizeY, const std::string & imageFilename, const std::string & SLFilename, bool readOnly, QWidget * parent):QWidget(parent) { this->screenSizeX = screenSizeX; this->screenSizeY = screenSizeY; readOnly = false; modificationInProgress = false; img = NULL; resizeFactor = 1; indexPointClicked = -1; maxLines = 0; loadImage(imageFilename); this->readOnly = readOnly; loadSL(SLFilename); } WorkArea::~WorkArea () { } void WorkArea::loadImage (const std::string & filename) { QImageReader qImgReader(QString::fromStdString (filename)); qImgReader.setAutoTransform(true); original = new QImage (qImgReader.read()); img = new QImage (original->scaled (screenSizeX, screenSizeY - this->geometry ().y (), Qt::KeepAspectRatio, Qt::FastTransformation)); resizeFactor = (img->width()*1.0)/original->width(); liste_points.clear (); setFixedSize (img->width (), img->height ()); } void WorkArea::loadSL (const std::string & filename) { liste_points.clear(); QFile fin(QString::fromStdString (filename)); fin.open(QIODevice::ReadOnly); QByteArray ba2 = fin.readAll(); QJsonParseError parseError; QJsonDocument doc2 = QJsonDocument::fromJson(ba2, &parseError); QJsonArray lines = doc2["lines"].toArray(); for(int i=0; ix ()/resizeFactor); point1.push_back(liste_points[i*2]->y ()/resizeFactor); line.push_back(point1); QJsonArray point2; point2.push_back(liste_points[i*2+1]->x ()/resizeFactor); point2.push_back(liste_points[i*2+1]->y ()/resizeFactor); line.push_back(point2); lines.push_back(line); } root["lines"] = lines; QByteArray ba = QJsonDocument(root).toJson(); QFile fout(QString::fromStdString (filename)); fout.open(QIODevice::WriteOnly); fout.write(ba); this->modificationInProgress = false; } void WorkArea::exportPNG (const std::string & filename) { QImage tempImg(*original); QPainter painter(&tempImg); for (int i = 0; i < liste_points.length (); i++) { if ((i % 2) == 1) { painter.setPen (QPen (Qt::red, epaisseurLigne/resizeFactor)); std::pair < QPoint *, QPoint * > endPoints = StrengthLine (liste_points[i - 1], liste_points[i]).toDraw (&tempImg); painter.drawLine (*(std::get < 0 > (endPoints))/resizeFactor, *(std::get < 1 > (endPoints))/resizeFactor); } } tempImg.save(QString::fromStdString (filename)); } void WorkArea::setReadOnly(bool readOnly){ this->readOnly = readOnly; } bool WorkArea::getReadOnly(){ return this->readOnly; } QImage* WorkArea::getOriginalImage() const { return new QImage(*original); } QImage* WorkArea::getResizedImage() const { return new QImage(*img); } void WorkArea::setModificationInProgress(bool mip){ this->modificationInProgress = mip; } bool WorkArea::getModificationInProgress(){ return this->modificationInProgress; } int WorkArea::getNumberOfLines() const { return ((int)(liste_points.size()/2)); } void WorkArea::addSL (const StrengthLine *sl) { liste_points << new QPoint((int)(sl->getP1()->x()*resizeFactor), (int)(sl->getP1()->y()*resizeFactor)); liste_points << new QPoint((int)(sl->getP2()->x()*resizeFactor), (int)(sl->getP2()->y()*resizeFactor)); } void WorkArea::addRandomSL () { StrengthLine *sl = StrengthLine::getRandomLine(original); liste_points << new QPoint((int)(sl->getP1()->x()*resizeFactor), (int)(sl->getP1()->y()*resizeFactor)); liste_points << new QPoint((int)(sl->getP2()->x()*resizeFactor), (int)(sl->getP2()->y()*resizeFactor)); } void WorkArea::paintEvent (QPaintEvent * event) { QPainter painter (this); paint (painter); } void WorkArea::paint (QPainter & painter) { if (img != NULL) painter.drawImage (0, 0, *img); for (int i = 0; i < liste_points.length (); i++) { if(readOnly==false) { painter.setBrush (QBrush (Qt::green)); painter.setPen (QPen (Qt::black)); painter.drawEllipse (liste_points[i]->x () - taillePoint / 2, liste_points[i]->y () - taillePoint / 2, taillePoint, taillePoint); } if ((i % 2) == 1) { painter.setPen (QPen (Qt::red, epaisseurLigne)); std::pair < QPoint *, QPoint * >endPoints = StrengthLine (liste_points[i - 1], liste_points[i]).toDraw (img); painter.drawLine (*(std::get < 0 > (endPoints)), *(std::get < 1 > (endPoints))); } } } void WorkArea::mousePressEvent (QMouseEvent * event) { if(readOnly==false) { if (img != NULL) { this->modificationInProgress = true; // Est ce qu'on a cliqué sur un point existant ? indexPointClicked = -1; for (int i = 0; i < liste_points.length (); i++) { QPoint point = event->pos () - *(liste_points[i]); if (point.manhattanLength () < taillePoint) { indexPointClicked = i; } } // Clic gauche if (event->button () == Qt::LeftButton) { if (indexPointClicked == -1) { if((maxLines == 0) || (liste_points.size()<(maxLines*2))){ indexPointClicked = liste_points.size (); liste_points << new QPoint (event->x (), event->y ()); } } } // Clic droit if (event->button () == Qt::RightButton) { if (indexPointClicked != -1) { if (indexPointClicked == (liste_points.size () - 1)) liste_points.removeAt (indexPointClicked); else { if ((indexPointClicked % 2) == 0) { QPoint *single = liste_points.takeAt (indexPointClicked + 1); liste_points.removeAt (indexPointClicked); liste_points << single; } else { QPoint *single = liste_points.takeAt (indexPointClicked - 1); liste_points.removeAt (indexPointClicked - 1); liste_points << single; } } indexPointClicked = -1; } } } } repaint (); } void WorkArea::mouseMoveEvent (QMouseEvent * event) { if(readOnly==false) { if (indexPointClicked != -1) { liste_points[indexPointClicked]->setX (event->x ()); liste_points[indexPointClicked]->setY (event->y ()); } } repaint (); } void WorkArea::mouseReleaseEvent (QMouseEvent * event) { indexPointClicked = -1; }