ImageView.cpp 11 KB

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