ImageView.cpp 11 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); // ����ͼƬƫ����Ϊ(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); // ����ͼƬƫ����Ϊ(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. // ��������û�� item ʱ�������ƶ�
  92. QPointF point = mapToScene(event->pos());
  93. if (scene()->itemAt(point, transform()) != nullptr
  94. && scene()->itemAt(point, transform())->type() == QGraphicsPixmapItem::Type) {
  95. setCursor(Qt::OpenHandCursor);
  96. m_bMouseTranslate = true;
  97. m_lastMousePos = event->pos();
  98. }
  99. }
  100. else if (event->button() == Qt::RightButton) {
  101. m_rightClickPressPos = event->pos();
  102. m_rightButtonPressed = true;
  103. if (m_bRulerState) {
  104. if (!m_isCreating) {
  105. // ��һ�ε������ʼ����
  106. m_isCreating = true;
  107. m_startPos = mapToScene(event->pos());
  108. m_pTempLine = scene()->addLine(QLineF(m_startPos, m_startPos),
  109. QPen(Qt::gray, 1, Qt::DashLine));
  110. m_pTempLine->setZValue(2);
  111. }
  112. else {
  113. // �ڶ��ε������ɴ���
  114. m_isCreating = false;
  115. QPointF endPos = mapToScene(event->pos());
  116. scene()->removeItem(m_pTempLine);
  117. delete m_pTempLine;
  118. RulerLineItem* ruler = new RulerLineItem(QLineF(m_startPos, endPos));
  119. ruler->setRulerText(tr("test ruler"));
  120. ruler->setZValue(2);
  121. scene()->addItem(ruler);
  122. }
  123. }
  124. event->accept();
  125. }
  126. QGraphicsView::mousePressEvent(event);
  127. }
  128. void ImageView::mouseMoveEvent(QMouseEvent* event) {
  129. if (m_isCreating && m_pTempLine) {
  130. QPointF currentPos = mapToScene(event->pos());
  131. m_pTempLine->setLine(QLineF(m_startPos, currentPos));
  132. }
  133. if (m_bMouseTranslate) {
  134. // ������굱ǰλ�����ϴ�λ�õIJ�ֵ
  135. QPointF delta = event->pos() - m_lastMousePos;
  136. // ƽ����ͼ
  137. horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
  138. verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
  139. m_lastMousePos = event->pos(); // ��������
  140. }
  141. else if ((event->buttons() & Qt::RightButton) && m_isDrawing && m_rightButtonPressed) {
  142. if (!m_curDrawing && (event->pos() - m_rightClickPressPos).manhattanLength() > 5) {
  143. m_curDrawing = true;
  144. // ���ݳ�ʼλ�ÿ�ʼ����·��
  145. QPointF scenePos = mapToScene(m_rightClickPressPos);
  146. m_currentPath = QPainterPath(scenePos);
  147. m_currentPathItem = new QGraphicsPathItem();
  148. m_currentPathItem->setPen(QPen(Qt::red, 2));
  149. m_currentPathItem->setPath(m_currentPath);
  150. m_currentPathItem->setZValue(2);
  151. scene()->addItem(m_currentPathItem);
  152. m_drawnPaths.append(m_currentPathItem);
  153. }
  154. if (m_curDrawing && m_currentPathItem) {
  155. QPointF scenePos = mapToScene(event->pos());
  156. m_currentPath.lineTo(scenePos);
  157. m_currentPathItem->setPath(m_currentPath);
  158. }
  159. event->accept();
  160. return;
  161. }
  162. QGraphicsView::mouseMoveEvent(event);
  163. }
  164. void ImageView::mouseReleaseEvent(QMouseEvent* event) {
  165. if (event->button() == Qt::LeftButton) {
  166. setCursor(Qt::ArrowCursor);
  167. m_bMouseTranslate = false;
  168. }
  169. else if (event->button() == Qt::RightButton && m_rightButtonPressed) {
  170. if (!m_curDrawing) {
  171. if (!m_bRulerState) {
  172. QMenu menu(this);
  173. QAction* act1 = menu.addAction(tr("save picture"));
  174. QAction* act2 = menu.addAction(tr("clear"));
  175. connect(act1, &QAction::triggered, this, [this]() {
  176. saveImage();
  177. });
  178. connect(act2, &QAction::triggered, this, [this]() {
  179. clearDrawnLines();
  180. });
  181. menu.exec(event->globalPos());
  182. }
  183. }
  184. else {
  185. m_currentPathItem = nullptr;
  186. m_curDrawing = false;
  187. }
  188. m_rightButtonPressed = false;
  189. event->accept();
  190. return;
  191. }
  192. QGraphicsView::mouseReleaseEvent(event);
  193. }
  194. void ImageView::wheelEvent(QWheelEvent* event)
  195. {
  196. if (event->orientation() == Qt::Vertical) {
  197. event->ignore(); // ������ֱ�����¼��������ù�����������
  198. return;
  199. }
  200. event->accept();
  201. }
  202. void ImageView::resizeEvent(QResizeEvent* event)
  203. {
  204. QGraphicsView::resizeEvent(event);
  205. viewport()->update(); // ���ڴ�С�ı�ʱ�ػ�ʮ����
  206. }
  207. void ImageView::scrollContentsBy(int dx, int dy)
  208. {
  209. QGraphicsView::scrollContentsBy(dx, dy);
  210. viewport()->update(); // ����ʱ����ʮ����
  211. }
  212. void ImageView::drawCrosshair(QPainter& painter)
  213. {
  214. const QRect viewRect = viewport()->rect();
  215. int resolutionWidth = viewRect.width();
  216. int resolutionHeight = viewRect.height();
  217. painter.setPen(QPen(QColor(139, 105, 20, 255), 1));
  218. // ���ƴ�ֱ��
  219. painter.drawLine(resolutionWidth / 2, 0, resolutionWidth / 2, resolutionHeight);
  220. // ����ˮƽ��
  221. painter.drawLine(0, resolutionHeight / 2, resolutionWidth, resolutionHeight / 2);
  222. int centerX = resolutionWidth / 2;
  223. int centerY = resolutionHeight / 2;
  224. int rulerLength = viewRect.width(); // ���߳���
  225. int tickSpacing = 5; // �̶ȼ��
  226. // ����ˮƽ�������ϵ�����
  227. int rulerStartXHorizontal = centerX;
  228. int rulerStartYHorizontal = centerY;
  229. for (int i = 0; i <= rulerLength / 2; i += tickSpacing) {
  230. int tickHeight = 0;
  231. if (i % (tickSpacing * 10) == 0) { // ���̶�
  232. tickHeight = 15;
  233. }
  234. else if (i % (tickSpacing * 5) == 0) { // �еȿ̶�
  235. tickHeight = 10;
  236. }
  237. else { // �̶̿�
  238. tickHeight = 5;
  239. }
  240. painter.drawLine(rulerStartXHorizontal + i, rulerStartYHorizontal, rulerStartXHorizontal + i, rulerStartYHorizontal - tickHeight); // ���ƿ̶���
  241. painter.drawLine(rulerStartXHorizontal - i, rulerStartYHorizontal, rulerStartXHorizontal - i, rulerStartYHorizontal - tickHeight); // ���ƿ̶���
  242. }
  243. // ���ƴ�ֱ�������ϵ�����
  244. int rulerStartXVertical = centerX;
  245. int rulerStartYVertical = centerY;
  246. for (int i = 0; i <= rulerLength / 2; i += tickSpacing) {
  247. int tickWidth = 0;
  248. if (i % (tickSpacing * 10) == 0) { // ���̶�
  249. tickWidth = 15;
  250. }
  251. else if (i % (tickSpacing * 5) == 0) { // �еȿ̶�
  252. tickWidth = 10;
  253. }
  254. else { // �̶̿�
  255. tickWidth = 5;
  256. }
  257. painter.drawLine(rulerStartXVertical, rulerStartYVertical - i, rulerStartXVertical - tickWidth, rulerStartYVertical - i);
  258. painter.drawLine(rulerStartXVertical, rulerStartYVertical + i, rulerStartXVertical - tickWidth, rulerStartYVertical + i);
  259. }
  260. }
  261. void ImageView::saveImage()
  262. {
  263. // ʹ�õ�ǰʱ������Ĭ���ļ���
  264. QString defaultFileName = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss") + ".png";
  265. QString fileName = QFileDialog::getSaveFileName(
  266. this,
  267. tr("����ͼƬ"),
  268. QDir::homePath() + "/" + defaultFileName, // Ĭ��·��Ϊ�û�Ŀ¼���ļ���Ϊ��ǰʱ��
  269. tr("PNG �ļ� (*.png);;JPEG �ļ� (*.jpg);;�����ļ� (*)")
  270. );
  271. if (!fileName.isEmpty()) {
  272. QImage image(viewport()->size(), QImage::Format_ARGB32);
  273. image.fill(Qt::white);
  274. QPainter painter(&image);
  275. this->render(&painter);
  276. if (!image.save(fileName)) {
  277. QMessageBox::warning(this, tr("����ʧ��"), tr("�޷�����ͼƬ��ָ��·����"));
  278. }
  279. else {
  280. QMessageBox::information(this, tr("����ɹ�"), tr("ͼƬ�ѳɹ����浽��") + fileName);
  281. }
  282. painter.end();
  283. }
  284. }
  285. void ImageView::clearDrawnLines()
  286. {
  287. qDeleteAll(m_drawnPaths);
  288. m_drawnPaths.clear();
  289. foreach(QGraphicsItem * item, scene()->selectedItems()) {
  290. if (nullptr == item)
  291. continue;
  292. scene()->removeItem(item);
  293. }
  294. }