coloringcanvas.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "coloringcanvas.h"
  2. #include <QtDeclarative>
  3. #include <QPainter>
  4. #include <QStyleOptionGraphicsItem>
  5. #include "drmimageprovider.h"
  6. ColoringCanvas::ColoringCanvas(QDeclarativeItem *parent):
  7. QDeclarativeItem(parent)
  8. {
  9. setFlag(QGraphicsItem::ItemHasNoContents, false);
  10. }
  11. void ColoringCanvas::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
  12. {
  13. painter->drawImage(option->rect, image_);
  14. }
  15. void ColoringCanvas::setColor(const QColor newColor)
  16. {
  17. if (color_ != newColor)
  18. {
  19. color_ = newColor;
  20. emit colorChanged();
  21. }
  22. }
  23. void ColoringCanvas::setSource(const QString& newSource)
  24. {
  25. if (source_.compare(newSource))
  26. {
  27. source_ = newSource;
  28. DrmImageProvider provider;
  29. QImage image = provider.requestImage(newSource,0,QSize(580,360));
  30. image_ = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, Qt::ColorOnly);
  31. update();
  32. emit sourceChanged();
  33. }
  34. }
  35. void ColoringCanvas::click(int x, int y)
  36. {
  37. QPoint fill;
  38. if (check(QPoint(x, y), fill))
  39. {
  40. floodFill(fill, color_.rgb());
  41. update();
  42. }
  43. }
  44. bool ColoringCanvas::check(const QPoint& point, QPoint& valid)
  45. {
  46. if (!image_.rect().contains(point)) return false;
  47. if (image_.pixel(point) != ignore_.rgb())
  48. {
  49. valid = point;
  50. return true;
  51. }
  52. return false;
  53. }
  54. bool ColoringCanvas::test(const QPoint& point, const QRgb& color)
  55. {
  56. if (!image_.rect().contains(point)) return false;
  57. return (image_.pixel(point) == color);
  58. }
  59. void ColoringCanvas::drawHorizontalLine(const QPoint & p1, const QPoint & p2, const QRgb& fillColor)
  60. {
  61. int x1 = p1.x();
  62. int x2 = p2.x();
  63. int y = p1.y();
  64. if (x1 > x2)
  65. {
  66. int temp = x1;
  67. x1 = x2;
  68. x2 = temp;
  69. }
  70. uchar* bytes = image_.scanLine(y);
  71. int* p = (int*)bytes;
  72. for (int i = x1; i <= x2; i++)
  73. {
  74. p[i] = fillColor;
  75. }
  76. }
  77. void ColoringCanvas::floodFill(const QPoint& point, const QRgb& fillColor)
  78. {
  79. if (!image_.rect().contains(point)) return;
  80. QRgb target = image_.pixel(point);
  81. if (target == fillColor) return;
  82. QStack<QPoint> stack;
  83. QPoint p;
  84. stack.reserve(1000);
  85. stack.push(point);
  86. while (!stack.isEmpty())
  87. {
  88. p = stack.pop();
  89. QPoint w = p;
  90. QPoint e = p;
  91. if (test(p + QPoint(0, 1), target))
  92. stack.push(p + QPoint(0, 1));
  93. if (test(p + QPoint(0, -1), target))
  94. stack.push(p + QPoint(0, -1));
  95. while (test(w + QPoint(-1, 0),target) && w.x() > 0)
  96. {
  97. w += QPoint(-1, 0);
  98. if (test(w + QPoint(0, 1), target))
  99. stack.push(w + QPoint(0, 1));
  100. if (test(w + QPoint(0, -1), target))
  101. stack.push(w + QPoint(0, -1));
  102. }
  103. while (test(e + QPoint(1, 0), target) && e.x() < image_.width()-1)
  104. {
  105. e += QPoint(1, 0);
  106. if (test(e + QPoint(0, 1), target))
  107. stack.push(e + QPoint(0, 1));
  108. if (test(e + QPoint(0, -1), target))
  109. stack.push(e + QPoint(0, -1));
  110. }
  111. drawHorizontalLine(w, e, fillColor);
  112. }
  113. }