imagecropperlabel.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. #include "imagecropperlabel.h"
  2. #include <QPainter>
  3. #include <QPainterPath>
  4. #include <QMouseEvent>
  5. #include <QDebug>
  6. #include <QBitmap>
  7. ImageCropperLabel::ImageCropperLabel(int width, int height, QWidget* parent) :
  8. QLabel(parent)
  9. {
  10. this->setFixedSize(width, height);
  11. this->setAlignment(Qt::AlignCenter);
  12. this->setMouseTracking(true);
  13. borderPen.setWidth(1);
  14. borderPen.setColor(Qt::white);
  15. borderPen.setDashPattern(QVector<qreal>() << 3 << 3 << 3 << 3);
  16. }
  17. void ImageCropperLabel::setOriginalImage(const QPixmap &pixmap) {
  18. originalImage = pixmap;
  19. int imgWidth = pixmap.width();
  20. int imgHeight = pixmap.height();
  21. int labelWidth = this->width();
  22. int labelHeight = this->height();
  23. int imgWidthInLabel;
  24. int imgHeightInLabel;
  25. if (imgWidth * labelHeight < imgHeight * labelWidth) {
  26. scaledRate = labelHeight / double(imgHeight);
  27. imgHeightInLabel = labelHeight;
  28. imgWidthInLabel = int(scaledRate * imgWidth);
  29. imageRect.setRect((labelWidth - imgWidthInLabel) / 2, 0,
  30. imgWidthInLabel, imgHeightInLabel);
  31. }
  32. else {
  33. scaledRate = labelWidth / double(imgWidth);
  34. imgWidthInLabel = labelWidth;
  35. imgHeightInLabel = int(scaledRate * imgHeight);
  36. imageRect.setRect(0, (labelHeight - imgHeightInLabel) / 2,
  37. imgWidthInLabel, imgHeightInLabel);
  38. }
  39. tempImage = originalImage.scaled(imgWidthInLabel, imgHeightInLabel,
  40. Qt::KeepAspectRatio, Qt::SmoothTransformation);
  41. this->setPixmap(tempImage);
  42. if (cropperShape >= CropperShape::FIXED_RECT) {
  43. cropperRect.setWidth(int(cropperRect_.width() * scaledRate));
  44. cropperRect.setHeight(int(cropperRect_.height() * scaledRate));
  45. }
  46. resetCropperPos();
  47. }
  48. /*****************************************
  49. * set cropper's shape (and size)
  50. *****************************************/
  51. void ImageCropperLabel::setRectCropper() {
  52. cropperShape = CropperShape::RECT;
  53. resetCropperPos();
  54. }
  55. void ImageCropperLabel::setSquareCropper() {
  56. cropperShape = CropperShape::SQUARE;
  57. resetCropperPos();
  58. }
  59. void ImageCropperLabel::setEllipseCropper() {
  60. cropperShape = CropperShape::ELLIPSE;
  61. resetCropperPos();
  62. }
  63. void ImageCropperLabel::setCircleCropper() {
  64. cropperShape = CropperShape::CIRCLE;
  65. resetCropperPos();
  66. }
  67. void ImageCropperLabel::setFixedRectCropper(QSize size) {
  68. cropperShape = CropperShape::FIXED_RECT;
  69. cropperRect_.setSize(size);
  70. resetCropperPos();
  71. }
  72. void ImageCropperLabel::setFixedEllipseCropper(QSize size) {
  73. cropperShape = CropperShape::FIXED_ELLIPSE;
  74. cropperRect_.setSize(size);
  75. resetCropperPos();
  76. }
  77. // not recommended
  78. void ImageCropperLabel::setCropper(CropperShape shape, QSize size) {
  79. cropperShape = shape;
  80. cropperRect_.setSize(size);
  81. resetCropperPos();
  82. }
  83. /*****************************************************************************
  84. * Set cropper's fixed size
  85. *****************************************************************************/
  86. void ImageCropperLabel::setCropperFixedSize(int fixedWidth, int fixedHeight) {
  87. cropperRect_.setSize(QSize(fixedWidth, fixedHeight));
  88. resetCropperPos();
  89. }
  90. void ImageCropperLabel::setCropperFixedWidth(int fixedWidth) {
  91. cropperRect_.setWidth(fixedWidth);
  92. resetCropperPos();
  93. }
  94. void ImageCropperLabel::setCropperFixedHeight(int fixedHeight) {
  95. cropperRect_.setHeight(fixedHeight);
  96. resetCropperPos();
  97. }
  98. /**********************************************
  99. * Move cropper to the center of the image
  100. * And resize to default
  101. **********************************************/
  102. void ImageCropperLabel::resetCropperPos() {
  103. int labelWidth = this->width();
  104. int labelHeight = this->height();
  105. if (cropperShape == CropperShape::FIXED_RECT || cropperShape == CropperShape::FIXED_ELLIPSE) {
  106. cropperRect.setWidth(int(cropperRect_.width() * scaledRate));
  107. cropperRect.setHeight(int(cropperRect_.height() * scaledRate));
  108. }
  109. switch (cropperShape) {
  110. case CropperShape::UNDEFINED:
  111. break;
  112. case CropperShape::FIXED_RECT:
  113. case CropperShape::FIXED_ELLIPSE: {
  114. cropperRect.setRect((labelWidth - cropperRect.width()) / 2,
  115. (labelHeight - cropperRect.height()) / 2,
  116. cropperRect.width(), cropperRect.height());
  117. break;
  118. }
  119. case CropperShape::RECT:
  120. case CropperShape::SQUARE:
  121. case CropperShape::ELLIPSE:
  122. case CropperShape::CIRCLE: {
  123. int imgWidth = tempImage.width();
  124. int imgHeight = tempImage.height();
  125. int edge = int((imgWidth > imgHeight ? imgHeight : imgWidth) * 3 / 4.0);
  126. cropperRect.setRect((labelWidth - edge) / 2, (labelHeight - edge) / 2, edge, edge);
  127. break;
  128. }
  129. }
  130. }
  131. QPixmap ImageCropperLabel::getCroppedImage() {
  132. return getCroppedImage(this->outputShape);
  133. }
  134. QPixmap ImageCropperLabel::getCroppedImage(OutputShape shape) {
  135. int startX = int((cropperRect.left() - imageRect.left()) / scaledRate);
  136. int startY = int((cropperRect.top() - imageRect.top()) / scaledRate);
  137. int croppedWidth = int(cropperRect.width() / scaledRate);
  138. int croppedHeight = int(cropperRect.height() / scaledRate);
  139. QPixmap resultImage(croppedWidth, croppedHeight);
  140. resultImage = originalImage.copy(startX, startY, croppedWidth, croppedHeight);
  141. // Set ellipse mask (cut to ellipse shape)
  142. if (shape == OutputShape::ELLIPSE) {
  143. QSize size(croppedWidth, croppedHeight);
  144. QBitmap mask(size);
  145. QPainter painter(&mask);
  146. painter.setRenderHint(QPainter::Antialiasing);
  147. painter.setRenderHint(QPainter::SmoothPixmapTransform);
  148. painter.fillRect(0, 0, size.width(), size.height(), Qt::white);
  149. painter.setBrush(QColor(0, 0, 0));
  150. painter.drawRoundRect(0, 0, size.width(), size.height(), 99, 99);
  151. resultImage.setMask(mask);
  152. }
  153. return resultImage;
  154. }
  155. void ImageCropperLabel::paintEvent(QPaintEvent *event) {
  156. // Draw original image
  157. QLabel::paintEvent(event);
  158. // Draw cropper and set some effects
  159. switch (cropperShape) {
  160. case CropperShape::UNDEFINED:
  161. break;
  162. case CropperShape::FIXED_RECT:
  163. drawRectOpacity();
  164. break;
  165. case CropperShape::FIXED_ELLIPSE:
  166. drawEllipseOpacity();
  167. break;
  168. case CropperShape::RECT:
  169. drawRectOpacity();
  170. drawSquareEdge(!ONLY_FOUR_CORNERS);
  171. break;
  172. case CropperShape::SQUARE:
  173. drawRectOpacity();
  174. drawSquareEdge(ONLY_FOUR_CORNERS);
  175. break;
  176. case CropperShape::ELLIPSE:
  177. drawEllipseOpacity();
  178. drawSquareEdge(!ONLY_FOUR_CORNERS);
  179. break;
  180. case CropperShape::CIRCLE:
  181. drawEllipseOpacity();
  182. drawSquareEdge(ONLY_FOUR_CORNERS);
  183. break;
  184. }
  185. // Draw cropper rect
  186. if (isShowRectBorder) {
  187. QPainter painter(this);
  188. painter.setPen(borderPen);
  189. painter.drawRect(cropperRect);
  190. }
  191. }
  192. void ImageCropperLabel::drawSquareEdge(bool onlyFourCorners) {
  193. if (!isShowDragSquare)
  194. return;
  195. // Four corners
  196. drawFillRect(cropperRect.topLeft(), dragSquareEdge, dragSquareColor);
  197. drawFillRect(cropperRect.topRight(), dragSquareEdge, dragSquareColor);
  198. drawFillRect(cropperRect.bottomLeft(), dragSquareEdge, dragSquareColor);
  199. drawFillRect(cropperRect.bottomRight(), dragSquareEdge, dragSquareColor);
  200. // Four edges
  201. if (!onlyFourCorners) {
  202. int centralX = cropperRect.left() + cropperRect.width() / 2;
  203. int centralY = cropperRect.top() + cropperRect.height() / 2;
  204. drawFillRect(QPoint(cropperRect.left(), centralY), dragSquareEdge, dragSquareColor);
  205. drawFillRect(QPoint(centralX, cropperRect.top()), dragSquareEdge, dragSquareColor);
  206. drawFillRect(QPoint(cropperRect.right(), centralY), dragSquareEdge, dragSquareColor);
  207. drawFillRect(QPoint(centralX, cropperRect.bottom()), dragSquareEdge, dragSquareColor);
  208. }
  209. }
  210. void ImageCropperLabel::drawFillRect(QPoint centralPoint, int edge, QColor color) {
  211. QRect rect(centralPoint.x() - edge / 2, centralPoint.y() - edge / 2, edge, edge);
  212. QPainter painter(this);
  213. painter.fillRect(rect, color);
  214. }
  215. // Opacity effect
  216. void ImageCropperLabel::drawOpacity(const QPainterPath& path) {
  217. QPainter painterOpac(this);
  218. painterOpac.setOpacity(opacity);
  219. painterOpac.fillPath(path, QBrush(Qt::black));
  220. }
  221. void ImageCropperLabel::drawRectOpacity() {
  222. if (isShowOpacityEffect) {
  223. QPainterPath p1, p2, p;
  224. p1.addRect(imageRect);
  225. p2.addRect(cropperRect);
  226. p = p1.subtracted(p2);
  227. drawOpacity(p);
  228. }
  229. }
  230. void ImageCropperLabel::drawEllipseOpacity() {
  231. if (isShowOpacityEffect) {
  232. QPainterPath p1, p2, p;
  233. p1.addRect(imageRect);
  234. p2.addEllipse(cropperRect);
  235. p = p1.subtracted(p2);
  236. drawOpacity(p);
  237. }
  238. }
  239. bool ImageCropperLabel::isPosNearDragSquare(const QPoint& pt1, const QPoint& pt2) {
  240. return abs(pt1.x() - pt2.x()) * 2 <= dragSquareEdge
  241. && abs(pt1.y() - pt2.y()) * 2 <= dragSquareEdge;
  242. }
  243. int ImageCropperLabel::getPosInCropperRect(const QPoint &pt) {
  244. if (isPosNearDragSquare(pt, QPoint(cropperRect.right(), cropperRect.center().y())))
  245. return RECT_RIGHT;
  246. if (isPosNearDragSquare(pt, cropperRect.bottomRight()))
  247. return RECT_BOTTOM_RIGHT;
  248. if (isPosNearDragSquare(pt, QPoint(cropperRect.center().x(), cropperRect.bottom())))
  249. return RECT_BOTTOM;
  250. if (isPosNearDragSquare(pt, cropperRect.bottomLeft()))
  251. return RECT_BOTTOM_LEFT;
  252. if (isPosNearDragSquare(pt, QPoint(cropperRect.left(), cropperRect.center().y())))
  253. return RECT_LEFT;
  254. if (isPosNearDragSquare(pt, cropperRect.topLeft()))
  255. return RECT_TOP_LEFT;
  256. if (isPosNearDragSquare(pt, QPoint(cropperRect.center().x(), cropperRect.top())))
  257. return RECT_TOP;
  258. if (isPosNearDragSquare(pt, cropperRect.topRight()))
  259. return RECT_TOP_RIGHT;
  260. if (cropperRect.contains(pt, true))
  261. return RECT_INSIDE;
  262. return RECT_OUTSIZD;
  263. }
  264. /*************************************************
  265. *
  266. * Change mouse cursor type
  267. * Arrow, SizeHor, SizeVer, etc...
  268. *
  269. *************************************************/
  270. void ImageCropperLabel::changeCursor() {
  271. switch (cursorPosInCropperRect) {
  272. case RECT_OUTSIZD:
  273. setCursor(Qt::ArrowCursor);
  274. break;
  275. case RECT_BOTTOM_RIGHT: {
  276. switch (cropperShape) {
  277. case CropperShape::SQUARE:
  278. case CropperShape::CIRCLE:
  279. case CropperShape::RECT:
  280. case CropperShape::ELLIPSE:
  281. setCursor(Qt::SizeFDiagCursor);
  282. break;
  283. default:
  284. break;
  285. }
  286. break;
  287. }
  288. case RECT_RIGHT: {
  289. switch (cropperShape) {
  290. case CropperShape::RECT:
  291. case CropperShape::ELLIPSE:
  292. setCursor(Qt::SizeHorCursor);
  293. break;
  294. default:
  295. break;
  296. }
  297. break;
  298. }
  299. case RECT_BOTTOM: {
  300. switch (cropperShape) {
  301. case CropperShape::RECT:
  302. case CropperShape::ELLIPSE:
  303. setCursor(Qt::SizeVerCursor);
  304. break;
  305. default:
  306. break;
  307. }
  308. break;
  309. }
  310. case RECT_BOTTOM_LEFT: {
  311. switch (cropperShape) {
  312. case CropperShape::RECT:
  313. case CropperShape::ELLIPSE:
  314. case CropperShape::SQUARE:
  315. case CropperShape::CIRCLE:
  316. setCursor(Qt::SizeBDiagCursor);
  317. break;
  318. default:
  319. break;
  320. }
  321. break;
  322. }
  323. case RECT_LEFT: {
  324. switch (cropperShape) {
  325. case CropperShape::RECT:
  326. case CropperShape::ELLIPSE:
  327. setCursor(Qt::SizeHorCursor);
  328. break;
  329. default:
  330. break;
  331. }
  332. break;
  333. }
  334. case RECT_TOP_LEFT: {
  335. switch (cropperShape) {
  336. case CropperShape::RECT:
  337. case CropperShape::ELLIPSE:
  338. case CropperShape::SQUARE:
  339. case CropperShape::CIRCLE:
  340. setCursor(Qt::SizeFDiagCursor);
  341. break;
  342. default:
  343. break;
  344. }
  345. break;
  346. }
  347. case RECT_TOP: {
  348. switch (cropperShape) {
  349. case CropperShape::RECT:
  350. case CropperShape::ELLIPSE:
  351. setCursor(Qt::SizeVerCursor);
  352. break;
  353. default:
  354. break;
  355. }
  356. break;
  357. }
  358. case RECT_TOP_RIGHT: {
  359. switch (cropperShape) {
  360. case CropperShape::SQUARE:
  361. case CropperShape::CIRCLE:
  362. case CropperShape::RECT:
  363. case CropperShape::ELLIPSE:
  364. setCursor(Qt::SizeBDiagCursor);
  365. break;
  366. default:
  367. break;
  368. }
  369. break;
  370. }
  371. case RECT_INSIDE: {
  372. setCursor(Qt::SizeAllCursor);
  373. break;
  374. }
  375. }
  376. }
  377. /*****************************************************
  378. *
  379. * Mouse Events
  380. *
  381. *****************************************************/
  382. void ImageCropperLabel::mousePressEvent(QMouseEvent *e) {
  383. currPos = lastPos = e->pos();
  384. isLButtonPressed = true;
  385. }
  386. void ImageCropperLabel::mouseMoveEvent(QMouseEvent *e) {
  387. currPos = e->pos();
  388. if (!isCursorPosCalculated) {
  389. cursorPosInCropperRect = getPosInCropperRect(currPos);
  390. changeCursor();
  391. }
  392. if (!isLButtonPressed)
  393. return;
  394. if (!imageRect.contains(currPos))
  395. return;
  396. isCursorPosCalculated = true;
  397. int xOffset = currPos.x() - lastPos.x();
  398. int yOffset = currPos.y() - lastPos.y();
  399. lastPos = currPos;
  400. int disX = 0;
  401. int disY = 0;
  402. // Move cropper
  403. switch (cursorPosInCropperRect) {
  404. case RECT_OUTSIZD:
  405. break;
  406. case RECT_BOTTOM_RIGHT: {
  407. disX = currPos.x() - cropperRect.left();
  408. disY = currPos.y() - cropperRect.top();
  409. switch (cropperShape) {
  410. case CropperShape::UNDEFINED:
  411. case CropperShape::FIXED_RECT:
  412. case CropperShape::FIXED_ELLIPSE:
  413. break;
  414. case CropperShape::SQUARE:
  415. case CropperShape::CIRCLE:
  416. setCursor(Qt::SizeFDiagCursor);
  417. if (disX >= cropperMinimumWidth && disY >= cropperMinimumHeight) {
  418. if (disX > disY && cropperRect.top() + disX <= imageRect.bottom()) {
  419. cropperRect.setRight(currPos.x());
  420. cropperRect.setBottom(cropperRect.top() + disX);
  421. emit croppedImageChanged();
  422. }
  423. else if (disX <= disY && cropperRect.left() + disY <= imageRect.right()) {
  424. cropperRect.setBottom(currPos.y());
  425. cropperRect.setRight(cropperRect.left() + disY);
  426. emit croppedImageChanged();
  427. }
  428. }
  429. break;
  430. case CropperShape::RECT:
  431. case CropperShape::ELLIPSE:
  432. setCursor(Qt::SizeFDiagCursor);
  433. if (disX >= cropperMinimumWidth) {
  434. cropperRect.setRight(currPos.x());
  435. emit croppedImageChanged();
  436. }
  437. if (disY >= cropperMinimumHeight) {
  438. cropperRect.setBottom(currPos.y());
  439. emit croppedImageChanged();
  440. }
  441. break;
  442. }
  443. break;
  444. }
  445. case RECT_RIGHT: {
  446. disX = currPos.x() - cropperRect.left();
  447. switch (cropperShape) {
  448. case CropperShape::UNDEFINED:
  449. case CropperShape::FIXED_RECT:
  450. case CropperShape::FIXED_ELLIPSE:
  451. case CropperShape::SQUARE:
  452. case CropperShape::CIRCLE:
  453. break;
  454. case CropperShape::RECT:
  455. case CropperShape::ELLIPSE:
  456. if (disX >= cropperMinimumWidth) {
  457. cropperRect.setRight(currPos.x());
  458. emit croppedImageChanged();
  459. }
  460. break;
  461. }
  462. break;
  463. }
  464. case RECT_BOTTOM: {
  465. disY = currPos.y() - cropperRect.top();
  466. switch (cropperShape) {
  467. case CropperShape::UNDEFINED:
  468. case CropperShape::FIXED_RECT:
  469. case CropperShape::FIXED_ELLIPSE:
  470. case CropperShape::SQUARE:
  471. case CropperShape::CIRCLE:
  472. break;
  473. case CropperShape::RECT:
  474. case CropperShape::ELLIPSE:
  475. if (disY >= cropperMinimumHeight) {
  476. cropperRect.setBottom(cropperRect.bottom() + yOffset);
  477. emit croppedImageChanged();
  478. }
  479. break;
  480. }
  481. break;
  482. }
  483. case RECT_BOTTOM_LEFT: {
  484. disX = cropperRect.right() - currPos.x();
  485. disY = currPos.y() - cropperRect.top();
  486. switch (cropperShape) {
  487. case CropperShape::UNDEFINED:
  488. break;
  489. case CropperShape::FIXED_RECT:
  490. case CropperShape::FIXED_ELLIPSE:
  491. case CropperShape::RECT:
  492. case CropperShape::ELLIPSE:
  493. if (disX >= cropperMinimumWidth) {
  494. cropperRect.setLeft(currPos.x());
  495. emit croppedImageChanged();
  496. }
  497. if (disY >= cropperMinimumHeight) {
  498. cropperRect.setBottom(currPos.y());
  499. emit croppedImageChanged();
  500. }
  501. break;
  502. case CropperShape::SQUARE:
  503. case CropperShape::CIRCLE:
  504. if (disX >= cropperMinimumWidth && disY >= cropperMinimumHeight) {
  505. if (disX > disY && cropperRect.top() + disX <= imageRect.bottom()) {
  506. cropperRect.setLeft(currPos.x());
  507. cropperRect.setBottom(cropperRect.top() + disX);
  508. emit croppedImageChanged();
  509. }
  510. else if (disX <= disY && cropperRect.right() - disY >= imageRect.left()) {
  511. cropperRect.setBottom(currPos.y());
  512. cropperRect.setLeft(cropperRect.right() - disY);
  513. emit croppedImageChanged();
  514. }
  515. }
  516. break;
  517. }
  518. break;
  519. }
  520. case RECT_LEFT: {
  521. disX = cropperRect.right() - currPos.x();
  522. switch (cropperShape) {
  523. case CropperShape::UNDEFINED:
  524. case CropperShape::FIXED_RECT:
  525. case CropperShape::FIXED_ELLIPSE:
  526. case CropperShape::SQUARE:
  527. case CropperShape::CIRCLE:
  528. break;
  529. case CropperShape::RECT:
  530. case CropperShape::ELLIPSE:
  531. if (disX >= cropperMinimumHeight) {
  532. cropperRect.setLeft(cropperRect.left() + xOffset);
  533. emit croppedImageChanged();
  534. }
  535. break;
  536. }
  537. break;
  538. }
  539. case RECT_TOP_LEFT: {
  540. disX = cropperRect.right() - currPos.x();
  541. disY = cropperRect.bottom() - currPos.y();
  542. switch (cropperShape) {
  543. case CropperShape::UNDEFINED:
  544. case CropperShape::FIXED_RECT:
  545. case CropperShape::FIXED_ELLIPSE:
  546. break;
  547. case CropperShape::RECT:
  548. case CropperShape::ELLIPSE:
  549. if (disX >= cropperMinimumWidth) {
  550. cropperRect.setLeft(currPos.x());
  551. emit croppedImageChanged();
  552. }
  553. if (disY >= cropperMinimumHeight) {
  554. cropperRect.setTop(currPos.y());
  555. emit croppedImageChanged();
  556. }
  557. break;
  558. case CropperShape::SQUARE:
  559. case CropperShape::CIRCLE:
  560. if (disX >= cropperMinimumWidth && disY >= cropperMinimumHeight) {
  561. if (disX > disY && cropperRect.bottom() - disX >= imageRect.top()) {
  562. cropperRect.setLeft(currPos.x());
  563. cropperRect.setTop(cropperRect.bottom() - disX);
  564. emit croppedImageChanged();
  565. }
  566. else if (disX <= disY && cropperRect.right() - disY >= imageRect.left()) {
  567. cropperRect.setTop(currPos.y());
  568. cropperRect.setLeft(cropperRect.right() - disY);
  569. emit croppedImageChanged();
  570. }
  571. }
  572. break;
  573. }
  574. break;
  575. }
  576. case RECT_TOP: {
  577. disY = cropperRect.bottom() - currPos.y();
  578. switch (cropperShape) {
  579. case CropperShape::UNDEFINED:
  580. case CropperShape::FIXED_RECT:
  581. case CropperShape::FIXED_ELLIPSE:
  582. case CropperShape::SQUARE:
  583. case CropperShape::CIRCLE:
  584. break;
  585. case CropperShape::RECT:
  586. case CropperShape::ELLIPSE:
  587. if (disY >= cropperMinimumHeight) {
  588. cropperRect.setTop(cropperRect.top() + yOffset);
  589. emit croppedImageChanged();
  590. }
  591. break;
  592. }
  593. break;
  594. }
  595. case RECT_TOP_RIGHT: {
  596. disX = currPos.x() - cropperRect.left();
  597. disY = cropperRect.bottom() - currPos.y();
  598. switch (cropperShape) {
  599. case CropperShape::UNDEFINED:
  600. case CropperShape::FIXED_RECT:
  601. case CropperShape::FIXED_ELLIPSE:
  602. break;
  603. case CropperShape::RECT:
  604. case CropperShape::ELLIPSE:
  605. if (disX >= cropperMinimumWidth) {
  606. cropperRect.setRight(currPos.x());
  607. emit croppedImageChanged();
  608. }
  609. if (disY >= cropperMinimumHeight) {
  610. cropperRect.setTop(currPos.y());
  611. emit croppedImageChanged();
  612. }
  613. break;
  614. case CropperShape::SQUARE:
  615. case CropperShape::CIRCLE:
  616. if (disX >= cropperMinimumWidth && disY >= cropperMinimumHeight) {
  617. if (disX < disY && cropperRect.left() + disY <= imageRect.right()) {
  618. cropperRect.setTop(currPos.y());
  619. cropperRect.setRight(cropperRect.left() + disY);
  620. emit croppedImageChanged();
  621. }
  622. else if (disX >= disY && cropperRect.bottom() - disX >= imageRect.top()) {
  623. cropperRect.setRight(currPos.x());
  624. cropperRect.setTop(cropperRect.bottom() - disX);
  625. emit croppedImageChanged();
  626. }
  627. }
  628. break;
  629. }
  630. break;
  631. }
  632. case RECT_INSIDE: {
  633. // Make sure the cropperRect is entirely inside the imageRecct
  634. if (xOffset > 0) {
  635. if (cropperRect.right() + xOffset > imageRect.right())
  636. xOffset = 0;
  637. }
  638. else if (xOffset < 0) {
  639. if (cropperRect.left() + xOffset < imageRect.left())
  640. xOffset = 0;
  641. }
  642. if (yOffset > 0) {
  643. if (cropperRect.bottom() + yOffset > imageRect.bottom())
  644. yOffset = 0;
  645. }
  646. else if (yOffset < 0) {
  647. if (cropperRect.top() + yOffset < imageRect.top())
  648. yOffset = 0;
  649. }
  650. cropperRect.moveTo(cropperRect.left() + xOffset, cropperRect.top() + yOffset);
  651. emit croppedImageChanged();
  652. }
  653. break;
  654. }
  655. repaint();
  656. }
  657. void ImageCropperLabel::mouseReleaseEvent(QMouseEvent *) {
  658. isLButtonPressed = false;
  659. isCursorPosCalculated = false;
  660. setCursor(Qt::ArrowCursor);
  661. }