123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #include "coloringcanvas.h"
- #include <QtDeclarative>
- #include <QPainter>
- #include <QStyleOptionGraphicsItem>
- #include "drmimageprovider.h"
- ColoringCanvas::ColoringCanvas(QDeclarativeItem *parent):
- QDeclarativeItem(parent)
- {
- setFlag(QGraphicsItem::ItemHasNoContents, false);
- }
- void ColoringCanvas::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
- {
- painter->drawImage(option->rect, image_);
- }
- void ColoringCanvas::setColor(const QColor newColor)
- {
- if (color_ != newColor)
- {
- color_ = newColor;
- emit colorChanged();
- }
- }
- void ColoringCanvas::setSource(const QString& newSource)
- {
- if (source_.compare(newSource))
- {
- source_ = newSource;
- DrmImageProvider provider;
- QImage image = provider.requestImage(newSource,0,QSize(580,360));
- image_ = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, Qt::ColorOnly);
- update();
- emit sourceChanged();
- }
- }
- void ColoringCanvas::click(int x, int y)
- {
- QPoint fill;
- if (check(QPoint(x, y), fill))
- {
- floodFill(fill, color_.rgb());
- update();
- }
- }
- bool ColoringCanvas::check(const QPoint& point, QPoint& valid)
- {
- if (!image_.rect().contains(point)) return false;
- if (image_.pixel(point) != ignore_.rgb())
- {
- valid = point;
- return true;
- }
- return false;
- }
- bool ColoringCanvas::test(const QPoint& point, const QRgb& color)
- {
- if (!image_.rect().contains(point)) return false;
- return (image_.pixel(point) == color);
- }
- void ColoringCanvas::drawHorizontalLine(const QPoint & p1, const QPoint & p2, const QRgb& fillColor)
- {
- int x1 = p1.x();
- int x2 = p2.x();
- int y = p1.y();
- if (x1 > x2)
- {
- int temp = x1;
- x1 = x2;
- x2 = temp;
- }
- uchar* bytes = image_.scanLine(y);
- int* p = (int*)bytes;
- for (int i = x1; i <= x2; i++)
- {
- p[i] = fillColor;
- }
- }
- void ColoringCanvas::floodFill(const QPoint& point, const QRgb& fillColor)
- {
- if (!image_.rect().contains(point)) return;
- QRgb target = image_.pixel(point);
- if (target == fillColor) return;
- QStack<QPoint> stack;
- QPoint p;
- stack.reserve(1000);
- stack.push(point);
- while (!stack.isEmpty())
- {
- p = stack.pop();
- QPoint w = p;
- QPoint e = p;
- if (test(p + QPoint(0, 1), target))
- stack.push(p + QPoint(0, 1));
- if (test(p + QPoint(0, -1), target))
- stack.push(p + QPoint(0, -1));
- while (test(w + QPoint(-1, 0),target) && w.x() > 0)
- {
- w += QPoint(-1, 0);
- if (test(w + QPoint(0, 1), target))
- stack.push(w + QPoint(0, 1));
- if (test(w + QPoint(0, -1), target))
- stack.push(w + QPoint(0, -1));
- }
- while (test(e + QPoint(1, 0), target) && e.x() < image_.width()-1)
- {
- e += QPoint(1, 0);
- if (test(e + QPoint(0, 1), target))
- stack.push(e + QPoint(0, 1));
- if (test(e + QPoint(0, -1), target))
- stack.push(e + QPoint(0, -1));
- }
- drawHorizontalLine(w, e, fillColor);
- }
- }
|