File indexing completed on 2024-04-21 03:50:55
0001 #include "image/imagepainter.h" 0002 #include "image/polygon.h" 0003 0004 #include <QGraphicsItem> 0005 0006 0007 ImagePainter::ImagePainter(Container* parent) : 0008 Painter(parent), 0009 m_shape(Shape::Polygon) 0010 { 0011 m_parent->setCurrentObject(new Polygon(m_parent->currentObject()->objClass())); 0012 m_parent->viewport()->installEventFilter(m_parent); 0013 m_parent->viewport()->setMouseTracking(false); 0014 } 0015 0016 ImagePainter::~ImagePainter() 0017 { 0018 if (m_items.isEmpty()) 0019 return; 0020 0021 for (QGraphicsItem* item : m_items) 0022 m_parent->scene()->removeItem(item); 0023 0024 m_items.clear(); 0025 0026 m_parent->scene()->removeItem(m_currentItem); 0027 } 0028 0029 void ImagePainter::paint(QPoint point, bool isDragging) 0030 { 0031 QGraphicsPixmapItem* currentItem = static_cast<QGraphicsPixmapItem*>(m_currentItem); 0032 if (currentItem != nullptr) { 0033 QPointF clickedPoint = m_parent->mapToScene(point); 0034 0035 bool isImageClicked = m_parent->scene()->itemAt(clickedPoint, m_parent->transform()) == currentItem; 0036 0037 Polygon* currentPolygon = static_cast<Polygon*>(m_parent->currentObject()); 0038 0039 if (m_shape == Shape::Polygon) { 0040 int idxSavedPolygClicked = -1; 0041 QPointF scaledClickedPoint = QPointF(-m_currentItem->pos()); 0042 scaledClickedPoint += QPointF(scaledClickedPoint.x()/m_scaleW, scaledClickedPoint.y()/m_scaleH); 0043 for (int i = 0; i < m_parent->savedObjects().size(); i++) { 0044 const Polygon* polygon = static_cast<const Polygon*>(m_parent->savedObjects()[i]); 0045 if (polygon->containsPoint(scaledClickedPoint, Qt::OddEvenFill)) { 0046 idxSavedPolygClicked = i; 0047 break; 0048 } 0049 } 0050 0051 bool isSavedPolygClicked = idxSavedPolygClicked != -1; 0052 if (isSavedPolygClicked) { 0053 if (isDragging) 0054 return; 0055 delete currentPolygon; 0056 m_parent->setCurrentObject(m_parent->savedObjects()[idxSavedPolygClicked]); 0057 m_parent->savedObjects().remove(idxSavedPolygClicked); 0058 currentPolygon = static_cast<Polygon*>(m_parent->currentObject()); 0059 currentPolygon->unscale(m_currentItem->pos(), m_scaleW, m_scaleH); 0060 currentPolygon->pop_back(); 0061 } 0062 0063 bool isPolygFirstPtClicked = false; 0064 if (!currentPolygon->empty()) { 0065 QPointF cPolygFirstPt = currentPolygon->first(); 0066 QRectF cPolygFirstPtRect(cPolygFirstPt, QPointF(cPolygFirstPt.x() + 10, cPolygFirstPt.y() + 10)); 0067 isPolygFirstPtClicked = cPolygFirstPtRect.contains(clickedPoint); 0068 if (isPolygFirstPtClicked) 0069 clickedPoint = cPolygFirstPt; 0070 } 0071 0072 if (isSavedPolygClicked || isPolygFirstPtClicked || isImageClicked) { 0073 *currentPolygon << clickedPoint; 0074 0075 if (currentPolygon->size() > 1 && currentPolygon->isClosed()) { 0076 currentPolygon->scale(m_currentItem->pos(), m_scaleW, m_scaleH); 0077 m_parent->appendObject(currentPolygon); 0078 m_parent->setCurrentObject(new Polygon(currentPolygon->objClass())); 0079 } 0080 0081 repaint(); 0082 } 0083 } 0084 else if (m_shape == Shape::Rectangle) { 0085 bool toSave = point.isNull() && currentPolygon->size() > 1; 0086 if (isImageClicked) { 0087 if (currentPolygon->empty()) 0088 *currentPolygon << clickedPoint; 0089 0090 else { 0091 QPointF firstPt = currentPolygon->first(); 0092 if (isDragging) { 0093 currentPolygon->clear(); 0094 *currentPolygon << firstPt; 0095 } 0096 else 0097 toSave = true; 0098 *currentPolygon << QPointF(clickedPoint.x(), firstPt.y()) << clickedPoint << QPointF(firstPt.x(), clickedPoint.y()) << firstPt; 0099 } 0100 0101 repaint(); 0102 } 0103 if (toSave) { 0104 currentPolygon->scale(m_currentItem->pos(), m_scaleW, m_scaleH); 0105 m_parent->appendObject(currentPolygon); 0106 m_parent->setCurrentObject(new Polygon(m_parent->currentObject()->objClass())); 0107 } 0108 } 0109 } 0110 } 0111 0112 void ImagePainter::changeItem(const QString& filepath) 0113 { 0114 QGraphicsPixmapItem* pixmapItem = nullptr; 0115 0116 if (filepath != "") { 0117 QPixmap image(filepath); 0118 QPixmap scaledImage; 0119 0120 if (image.height() >= 1280) 0121 scaledImage = image.scaledToHeight(int(1280 * 0.8)); 0122 0123 if (image.width() >= 960) 0124 scaledImage = image.scaledToWidth(int(960 * 0.8)); 0125 0126 if (!scaledImage.isNull()) { 0127 m_scaleW = qreal(scaledImage.width()) / qreal(image.width()); 0128 m_scaleH = qreal(scaledImage.height()) / qreal(image.height()); 0129 image = scaledImage; 0130 } 0131 else { 0132 m_scaleW = 1.0; 0133 m_scaleH = 1.0; 0134 } 0135 0136 pixmapItem = m_parent->scene()->addPixmap(image); 0137 0138 int x_scene = int(m_parent->scene()->width() / 2); 0139 int y_scene = int(m_parent->scene()->height() / 2); 0140 int x_image = int(image.width() / 2); 0141 int y_image = int(image.height() / 2); 0142 0143 pixmapItem->setPos(x_scene - x_image, y_scene - y_image); 0144 } 0145 0146 m_currentItem = pixmapItem; 0147 m_filepath = filepath; 0148 } 0149 0150 void ImagePainter::repaint() 0151 { 0152 for (QGraphicsItem* item : m_items) 0153 m_parent->scene()->removeItem(item); 0154 0155 m_items.clear(); 0156 0157 for (MarkedObject* obj : m_parent->savedObjects()) 0158 paintObject(obj); 0159 0160 paintObject(m_parent->currentObject()); 0161 } 0162 0163 void ImagePainter::undo() 0164 { 0165 Polygon* polygon = static_cast<Polygon*>(m_parent->currentObject()); 0166 0167 if (!polygon->empty()) { 0168 polygon->pop_back(); 0169 repaint(); 0170 } 0171 } 0172 0173 void ImagePainter::deleteCurrentObject() 0174 { 0175 Polygon* polygon = static_cast<Polygon*>(m_parent->currentObject()); 0176 0177 if (!polygon->isClosed()) { 0178 polygon->clear(); 0179 repaint(); 0180 } 0181 } 0182 0183 void ImagePainter::paintObject(MarkedObject* object) 0184 { 0185 Polygon polygon (static_cast<const Polygon*>(object)); 0186 if (object != m_parent->currentObject()) { 0187 QPointF offset = m_currentItem->pos(); 0188 for (QPointF& point : polygon) { 0189 point = QPointF(point.x() * m_scaleW, point.y() * m_scaleH); 0190 point += offset; 0191 } 0192 } 0193 0194 QColor color(polygon.objClass()->color()); 0195 QBrush brush(color); 0196 QPen pen(brush, 2); 0197 0198 if (polygon.size() > 1 && polygon.isClosed()) { 0199 color.setAlpha(35); 0200 0201 QGraphicsPolygonItem* pol = m_parent->scene()->addPolygon(polygon, pen, QBrush(color)); 0202 0203 m_items << pol; 0204 } 0205 else { 0206 for (auto it = polygon.begin(); it != polygon.end(); ++it) { 0207 QGraphicsItem* item; 0208 if (it == polygon.begin()) 0209 item = m_parent->scene()->addRect((*it).x(), (*it).y(), 10, 10, pen, brush); 0210 else 0211 item = m_parent->scene()->addLine(QLineF(*(it - 1), *it), pen); 0212 0213 m_items << item; 0214 } 0215 } 0216 } 0217 0218 bool ImagePainter::importObjects(QVector<MarkedObject*> objects) 0219 { 0220 if (objects.isEmpty() || objects.first()->type() != MarkedObject::Type::Polygon) 0221 return false; 0222 0223 m_parent->savedObjects() = objects; 0224 repaint(); 0225 0226 return true; 0227 } 0228 0229 void ImagePainter::zoomIn() 0230 { 0231 m_parent->currentObject()->clear(); 0232 if (m_scaleH < 4.0 && m_scaleW < 4.0) 0233 scaleImage(1.25); 0234 } 0235 0236 void ImagePainter::zoomOut() 0237 { 0238 m_parent->currentObject()->clear(); 0239 if (m_scaleH > 0.25 && m_scaleW > 0.25) 0240 scaleImage(0.75); 0241 } 0242 0243 void ImagePainter::scaleImage(double factor) 0244 { 0245 if (m_filepath != "") { 0246 m_scaleH *= factor; 0247 m_scaleW *= factor; 0248 0249 QPixmap image(m_filepath); 0250 QPixmap scaledImage; 0251 0252 scaledImage = image.scaledToHeight(int(image.height() * m_scaleH)); 0253 scaledImage = image.scaledToWidth(int(image.width() * m_scaleW)); 0254 0255 image = scaledImage; 0256 0257 m_parent->scene()->removeItem(m_currentItem); 0258 QGraphicsPixmapItem* pixmapItem = m_parent->scene()->addPixmap(image); 0259 0260 int x_scene = int(m_parent->scene()->width() / 2); 0261 int y_scene = int(m_parent->scene()->height() / 2); 0262 int x_image = int(image.width() / 2); 0263 int y_image = int(image.height() / 2); 0264 0265 pixmapItem->setPos(x_scene - x_image, y_scene - y_image); 0266 m_currentItem = pixmapItem; 0267 0268 repaint(); 0269 } 0270 }