ImageView.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include "ImageView.h"
  2. #include <QPainter>
  3. #include <QDebug>
  4. #include <QGraphicsPixmapItem>
  5. #include <QScrollBar>
  6. #include <QMenu>
  7. #include <QFileDialog>
  8. #include <QDateTime>
  9. #include <QMessageBox>
  10. #include <QApplication>
  11. #define VIEW_CENTER viewport()->rect().center()
  12. #define VIEW_WIDTH viewport()->rect().width()
  13. #define VIEW_HEIGHT viewport()->rect().height()
  14. ImageView::ImageView(QWidget* parent) :
  15. QGraphicsView(parent),
  16. m_imageOffset(0, 0),
  17. m_bMouseTranslate(false),
  18. m_isDrawing(false),
  19. m_curDrawing(false),
  20. m_isCreating(false),
  21. m_currentPathItem(nullptr)
  22. {
  23. // m_rubberBand = nullptr;
  24. m_bRulerState = false;
  25. m_pRuleLine = nullptr;
  26. setScene(new QGraphicsScene(this));
  27. setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  28. this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  29. this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  30. //设置视图属性
  31. //setRenderHint(QPainter::SmoothPixmapTransform);
  32. setRenderHint(QPainter::Antialiasing);
  33. setMouseTracking(true);
  34. setDragMode(RubberBandDrag);
  35. }
  36. ImageView::~ImageView()
  37. {
  38. }
  39. void ImageView::setPixmap(const QPixmap& newPixmap) {
  40. this->m_pixmap = newPixmap;
  41. scene()->clear();
  42. m_pixmapItem = scene()->addPixmap(m_pixmap);
  43. m_pixmapItem->setZValue(1);
  44. QPointF pixmapCenter(m_pixmap.width() / 2.0, m_pixmap.height() / 2.0);
  45. m_pixmapItem->setPos(-pixmapCenter);
  46. QRectF sceneRect(-pixmapCenter.x(), -pixmapCenter.y(), m_pixmap.width(), m_pixmap.height());
  47. scene()->setSceneRect(sceneRect);
  48. setSceneRect(scene()->itemsBoundingRect());
  49. this->resize(m_pixmap.width(), m_pixmap.height());
  50. m_imageOffset = QPoint(0, 0);
  51. setCursor(Qt::ArrowCursor);
  52. update();
  53. }
  54. void ImageView::setCurPixmap(const QPixmap& newPixmap) {
  55. if (this->m_pixmap.isNull()) {
  56. this->m_pixmap = newPixmap;
  57. scene()->clear();
  58. m_pixmapItem = scene()->addPixmap(m_pixmap);
  59. m_pixmapItem->setZValue(1);
  60. QPointF pixmapCenter(m_pixmap.width() / 2.0, m_pixmap.height() / 2.0);
  61. m_pixmapItem->setPos(-pixmapCenter);
  62. QRectF sceneRect(-pixmapCenter.x(), -pixmapCenter.y(), m_pixmap.width(), m_pixmap.height());
  63. scene()->setSceneRect(sceneRect);
  64. setSceneRect(scene()->itemsBoundingRect());
  65. //this->resize(m_pixmap.width(), m_pixmap.height());
  66. m_imageOffset = QPoint(0, 0);
  67. setCursor(Qt::ArrowCursor);
  68. update();
  69. }
  70. else {
  71. this->m_pixmap = newPixmap;
  72. m_pixmapItem->setPixmap(m_pixmap);
  73. }
  74. }
  75. void ImageView::addRuler()
  76. {
  77. m_bRulerState = true;
  78. }
  79. void ImageView::cancelRuler()
  80. {
  81. m_bRulerState = false;
  82. }
  83. void ImageView::paintEvent(QPaintEvent* event) {
  84. QGraphicsView::paintEvent(event);
  85. QPainter painter(viewport());
  86. painter.setRenderHint(QPainter::Antialiasing);
  87. drawCrosshair(painter);
  88. }
  89. void ImageView::mousePressEvent(QMouseEvent* event) {
  90. if (event->button() == Qt::LeftButton) {
  91. QPointF point = mapToScene(event->pos());
  92. if (scene()->itemAt(point, transform()) != nullptr
  93. && scene()->itemAt(point, transform())->type() == QGraphicsPixmapItem::Type) {
  94. setCursor(Qt::OpenHandCursor);
  95. m_bMouseTranslate = true;
  96. m_lastMousePos = event->pos();
  97. }
  98. }
  99. else if (event->button() == Qt::RightButton) {
  100. m_rightClickPressPos = event->pos();
  101. m_rightButtonPressed = true;
  102. if (m_bRulerState) {
  103. if (!m_isCreating) {
  104. m_isCreating = true;
  105. m_startPos = mapToScene(event->pos());
  106. m_pTempLine = scene()->addLine(QLineF(m_startPos, m_startPos),
  107. QPen(Qt::gray, 1, Qt::DashLine));
  108. m_pTempLine->setZValue(2);
  109. }
  110. else {
  111. m_isCreating = false;
  112. QPointF endPos = mapToScene(event->pos());
  113. scene()->removeItem(m_pTempLine);
  114. delete m_pTempLine;
  115. RulerLineItem* ruler = new RulerLineItem(QLineF(m_startPos, endPos));
  116. ruler->setRulerText(tr("test ruler"));
  117. ruler->setZValue(2);
  118. scene()->addItem(ruler);
  119. }
  120. }
  121. event->accept();
  122. }
  123. QGraphicsView::mousePressEvent(event);
  124. }
  125. void ImageView::mouseMoveEvent(QMouseEvent* event) {
  126. if (m_isCreating && m_pTempLine) {
  127. QPointF currentPos = mapToScene(event->pos());
  128. m_pTempLine->setLine(QLineF(m_startPos, currentPos));
  129. }
  130. if (m_bMouseTranslate) {
  131. QPointF delta = event->pos() - m_lastMousePos;
  132. horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
  133. verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
  134. m_lastMousePos = event->pos();
  135. }
  136. else if ((event->buttons() & Qt::RightButton) && m_isDrawing && m_rightButtonPressed) {
  137. if (!m_curDrawing && (event->pos() - m_rightClickPressPos).manhattanLength() > 5) {
  138. m_curDrawing = true;
  139. QPointF scenePos = mapToScene(m_rightClickPressPos);
  140. m_currentPath = QPainterPath(scenePos);
  141. m_currentPathItem = new QGraphicsPathItem();
  142. m_currentPathItem->setPen(QPen(Qt::red, 2));
  143. m_currentPathItem->setPath(m_currentPath);
  144. m_currentPathItem->setZValue(2);
  145. scene()->addItem(m_currentPathItem);
  146. m_drawnPaths.append(m_currentPathItem);
  147. }
  148. if (m_curDrawing && m_currentPathItem) {
  149. QPointF scenePos = mapToScene(event->pos());
  150. m_currentPath.lineTo(scenePos);
  151. m_currentPathItem->setPath(m_currentPath);
  152. }
  153. event->accept();
  154. return;
  155. }
  156. QGraphicsView::mouseMoveEvent(event);
  157. }
  158. void ImageView::mouseReleaseEvent(QMouseEvent* event) {
  159. if (event->button() == Qt::LeftButton) {
  160. setCursor(Qt::ArrowCursor);
  161. m_bMouseTranslate = false;
  162. }
  163. else if (event->button() == Qt::RightButton && m_rightButtonPressed) {
  164. if (!m_curDrawing) {
  165. if (!m_bRulerState) {
  166. QMenu menu(this);
  167. QAction* act1 = menu.addAction(tr("save picture"));
  168. QAction* act2 = menu.addAction(tr("clear"));
  169. connect(act1, &QAction::triggered, this, [this]() {
  170. saveImage();
  171. });
  172. connect(act2, &QAction::triggered, this, [this]() {
  173. clearDrawnLines();
  174. });
  175. menu.exec(event->globalPos());
  176. }
  177. }
  178. else {
  179. m_currentPathItem = nullptr;
  180. m_curDrawing = false;
  181. }
  182. m_rightButtonPressed = false;
  183. event->accept();
  184. return;
  185. }
  186. QGraphicsView::mouseReleaseEvent(event);
  187. }
  188. void ImageView::wheelEvent(QWheelEvent* event)
  189. {
  190. if (event->orientation() == Qt::Vertical) {
  191. event->ignore();
  192. return;
  193. }
  194. event->accept();
  195. }
  196. void ImageView::resizeEvent(QResizeEvent* event)
  197. {
  198. QGraphicsView::resizeEvent(event);
  199. viewport()->update();
  200. }
  201. void ImageView::scrollContentsBy(int dx, int dy)
  202. {
  203. QGraphicsView::scrollContentsBy(dx, dy);
  204. viewport()->update();
  205. }
  206. void ImageView::drawCrosshair(QPainter& painter)
  207. {
  208. const QRect viewRect = viewport()->rect();
  209. int resolutionWidth = viewRect.width();
  210. int resolutionHeight = viewRect.height();
  211. painter.setPen(QPen(QColor(139, 105, 20, 255), 1));
  212. painter.drawLine(resolutionWidth / 2, 0, resolutionWidth / 2, resolutionHeight);
  213. painter.drawLine(0, resolutionHeight / 2, resolutionWidth, resolutionHeight / 2);
  214. int centerX = resolutionWidth / 2;
  215. int centerY = resolutionHeight / 2;
  216. int rulerLength = viewRect.width();
  217. int tickSpacing = 5;
  218. int rulerStartXHorizontal = centerX;
  219. int rulerStartYHorizontal = centerY;
  220. for (int i = 0; i <= rulerLength / 2; i += tickSpacing) {
  221. int tickHeight = 0;
  222. if (i % (tickSpacing * 10) == 0) {
  223. tickHeight = 30;
  224. }
  225. else if (i % (tickSpacing * 5) == 0) {
  226. tickHeight = 15;
  227. }
  228. else {
  229. tickHeight = 5;
  230. }
  231. painter.drawLine(rulerStartXHorizontal + i, rulerStartYHorizontal + tickHeight, rulerStartXHorizontal + i, rulerStartYHorizontal - tickHeight);
  232. painter.drawLine(rulerStartXHorizontal - i, rulerStartYHorizontal + tickHeight, rulerStartXHorizontal - i, rulerStartYHorizontal - tickHeight);
  233. }
  234. int rulerStartXVertical = centerX;
  235. int rulerStartYVertical = centerY;
  236. for (int i = 0; i <= rulerLength / 2; i += tickSpacing) {
  237. int tickWidth = 0;
  238. if (i % (tickSpacing * 10) == 0) {
  239. tickWidth = 15;
  240. }
  241. else if (i % (tickSpacing * 5) == 0) {
  242. tickWidth = 10;
  243. }
  244. else {
  245. tickWidth = 5;
  246. }
  247. painter.drawLine(rulerStartXVertical+ tickWidth, rulerStartYVertical - i, rulerStartXVertical - tickWidth, rulerStartYVertical - i);
  248. painter.drawLine(rulerStartXVertical + tickWidth, rulerStartYVertical + i, rulerStartXVertical - tickWidth, rulerStartYVertical + i);
  249. }
  250. }
  251. void ImageView::saveImage()
  252. {
  253. QString defaultFileName = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss") + ".png";
  254. QString fileName = QFileDialog::getSaveFileName(
  255. this,
  256. tr("save picture"),
  257. QDir::homePath() + "/" + defaultFileName,
  258. tr("PNG (*.png);;JPEG (*.jpg);; (*)")
  259. );
  260. if (!fileName.isEmpty()) {
  261. QImage image(viewport()->size(), QImage::Format_ARGB32);
  262. image.fill(Qt::white);
  263. QPainter painter(&image);
  264. this->render(&painter);
  265. if (!image.save(fileName)) {
  266. QMessageBox::warning(this,tr("save failed"),tr("The picture cannot be saved to the specified path"));
  267. }
  268. else {
  269. QMessageBox::information(this, tr("save sucessful"),tr("The picture has been successfully saved to:") + fileName);
  270. }
  271. painter.end();
  272. }
  273. }
  274. void ImageView::clearDrawnLines()
  275. {
  276. qDeleteAll(m_drawnPaths);
  277. m_drawnPaths.clear();
  278. foreach(QGraphicsItem * item, scene()->selectedItems()) {
  279. if (nullptr == item)
  280. continue;
  281. scene()->removeItem(item);
  282. }
  283. }