diff --git a/src/Painting/GUI/IntelliPhotoGui.h b/src/Painting/GUI/IntelliPhotoGui.h index fa36326..c872ab8 100644 --- a/src/Painting/GUI/IntelliPhotoGui.h +++ b/src/Painting/GUI/IntelliPhotoGui.h @@ -73,7 +73,8 @@ private: bool saveFile(const QByteArray &fileFormat); // What we'll draw on - PaintingArea *paintingArea; + PaintingArea* paintingArea; + // The menu widgets QMenu *saveAsMenu; diff --git a/src/Painting/Image/IntelliImage.cpp b/src/Painting/Image/IntelliImage.cpp index 879e8c7..814aa36 100644 --- a/src/Painting/Image/IntelliImage.cpp +++ b/src/Painting/Image/IntelliImage.cpp @@ -71,11 +71,3 @@ void IntelliImage::floodFill(const QColor& color){ imageData.fill(color); } - -int IntelliImage::x(){ - return imageData.size().width(); -} - -int IntelliImage::y(){ - return imageData.size().height(); -} diff --git a/src/Painting/Image/IntelliImage.h b/src/Painting/Image/IntelliImage.h index a2fb3c0..894093c 100644 --- a/src/Painting/Image/IntelliImage.h +++ b/src/Painting/Image/IntelliImage.h @@ -13,20 +13,26 @@ enum class ImageType{ Shaped_Image }; -class IntelliImage{ +class IntelliTool; +class IntelliImage{ + friend IntelliTool; protected: void resizeImage(QImage *image, const QSize &newSize); + virtual void calculateVisiblity()=0; QImage imageData; + + //calculate with polygon public: IntelliImage(int weight, int height); virtual ~IntelliImage() = 0; //start on top left - virtual void drawPixel(const QPoint &p1, const QColor& color); - virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); - virtual void floodFill(const QColor& color); + //TODO give tool refrence of image, -> funtkions will not be needed + virtual void drawPixel(const QPoint &p1, const QColor& color); + virtual void drawLine(const QPoint &p1, const QPoint& p2, const QColor& color, const int& penWidth); + virtual void floodFill(const QColor& color); //returns the filtered output virtual QImage getDisplayable(const QSize& displaySize, int alpha)=0; @@ -37,10 +43,9 @@ public: //sets the data for the visible image virtual void setPolygon(const std::vector& polygonData)=0; - virtual bool loadImage(const QString &fileName); - int x(); - int y(); + //loads an image to the ColorBuffer + virtual bool loadImage(const QString &fileName); }; #endif diff --git a/src/Painting/Image/IntelliRasterImage.cpp b/src/Painting/Image/IntelliRasterImage.cpp index b73c264..3cedbeb 100644 --- a/src/Painting/Image/IntelliRasterImage.cpp +++ b/src/Painting/Image/IntelliRasterImage.cpp @@ -12,6 +12,10 @@ IntelliRasterImage::~IntelliRasterImage(){ } +void IntelliRasterImage::calculateVisiblity(){ + +} + QImage IntelliRasterImage::getDisplayable(int alpha){ return getDisplayable(imageData.size(), alpha); } diff --git a/src/Painting/Image/IntelliRasterImage.h b/src/Painting/Image/IntelliRasterImage.h index 3b3e600..2d6d809 100644 --- a/src/Painting/Image/IntelliRasterImage.h +++ b/src/Painting/Image/IntelliRasterImage.h @@ -4,7 +4,8 @@ #include"Image/IntelliImage.h" class IntelliRasterImage : public IntelliImage{ - +protected: + virtual void calculateVisiblity() override; public: IntelliRasterImage(int weight, int height); virtual ~IntelliRasterImage() override; diff --git a/src/Painting/Image/IntelliShapedImage.cpp b/src/Painting/Image/IntelliShapedImage.cpp index 6b7a829..7baf81c 100644 --- a/src/Painting/Image/IntelliShapedImage.cpp +++ b/src/Painting/Image/IntelliShapedImage.cpp @@ -13,59 +13,66 @@ IntelliShapedImage::~IntelliShapedImage(){ } QImage IntelliShapedImage::getDisplayable(int alpha){ - return getDisplayable(imageData.size()); + return getDisplayable(imageData.size(),alpha); +} + +void IntelliShapedImage::calculateVisiblity(){ + if(polygonData.size()<=2){ + QColor clr; + for(int y=0; y(polygonData.size()-1); i++){ + QPoint B = polygonData[static_cast(i)]; + QPoint C = polygonData[static_cast(i+1)]; + QPoint P(x,y); + cutNumeber+=IntelliHelper::isInTriangle(A,B,C,P); + } + if(cutNumeber%2==0){ + clr = imageData.pixelColor(x,y); + clr.setAlpha(0); + imageData.setPixelColor(x,y,clr); + }else{ + clr = imageData.pixelColor(x,y); + clr.setAlpha(255); + imageData.setPixelColor(x,y,clr); + } + } + } } QImage IntelliShapedImage::getDisplayable(const QSize& displaySize, int alpha){ - if(polygonData.size()==0){ - QImage copy = imageData; - for(int y = 0; y not in Polygon - if(!(cutNumberX&1)){ - QColor tmpColor(0,0,0); - tmpColor.setAlpha(0); - copy.setPixelColor(startPoint,tmpColor); - }else{ - QColor clr = copy.pixelColor(x,y); - clr.setAlpha(alpha); - copy.setPixelColor(x,y,clr); - } + for(int x = 0; x& polygonData){ if(polygonData.size()<3){ - return; - } - for(auto element:polygonData){ - this->polygonData.push_back(QPoint(element.x(), element.y())); + this->polygonData.clear(); + }else{ + this->polygonData.clear(); + for(auto element:polygonData){ + this->polygonData.push_back(QPoint(element.x(), element.y())); + } } + calculateVisiblity(); return; } diff --git a/src/Painting/Image/IntelliShapedImage.h b/src/Painting/Image/IntelliShapedImage.h index 6c38366..0039c3b 100644 --- a/src/Painting/Image/IntelliShapedImage.h +++ b/src/Painting/Image/IntelliShapedImage.h @@ -6,6 +6,7 @@ class IntelliShapedImage : public IntelliImage{ protected: + virtual void calculateVisiblity() override; std::vector polygonData; public: IntelliShapedImage(int weight, int height); diff --git a/src/Painting/IntelliHelper/IntelliHelper.cpp b/src/Painting/IntelliHelper/IntelliHelper.cpp index ef0e8fb..0cd9460 100644 --- a/src/Painting/IntelliHelper/IntelliHelper.cpp +++ b/src/Painting/IntelliHelper/IntelliHelper.cpp @@ -1,39 +1,4 @@ #include"IntelliHelper.h" #include -int IntelliHelper::orientation(QPoint& p, QPoint& q, QPoint& r){ - int value = (q.y()-p.y())*(r.x()-q.x())- - (q.x()-p.x())*(r.y()-q.y()); - if(value==0) return 0; - return (value>0)?1:2; -} -bool IntelliHelper::onSegment(QPoint& p1, QPoint& q, QPoint& p2){ - return (q.x() >= std::min(p1.x(),p2.x()) && q.x() <= std::max(p1.x(), p2.x()) && - q.y() >= std::min(p1.y(),p2.y()) && q.y() <= std::max(p1.y(), p2.y())); -} - -bool IntelliHelper::hasIntersection(QPoint& p1, QPoint& q1, QPoint& p2, QPoint& q2){ - int o1 = IntelliHelper::orientation(p1,q1,p2); - int o2 = IntelliHelper::orientation(p1,q1,q2); - int o3 = IntelliHelper::orientation(p2,q2,p1); - int o4 = IntelliHelper::orientation(p2,q2,q1); - - // General case - if (o1 != o2 && o3 != o4) - return true; - - // p1, q1 and p2 are colinear and p2 lies on segment p1q1 - if (o1 == 0 && onSegment(p1, p2, q1)) return true; - - // p1, q1 and q2 are colinear and q2 lies on segment p1q1 - if (o2 == 0 && onSegment(p1, q2, q1)) return true; - - // p2, q2 and p1 are colinear and p1 lies on segment p2q2 - if (o3 == 0 && onSegment(p2, p1, q2)) return true; - - // p2, q2 and q1 are colinear and q1 lies on segment p2q2 - if (o4 == 0 && onSegment(p2, q1, q2)) return true; - - return false; // Doesn't fall in any of the above cases -} diff --git a/src/Painting/IntelliHelper/IntelliHelper.h b/src/Painting/IntelliHelper/IntelliHelper.h index 9e273f6..ef6b32a 100644 --- a/src/Painting/IntelliHelper/IntelliHelper.h +++ b/src/Painting/IntelliHelper/IntelliHelper.h @@ -5,18 +5,27 @@ class IntelliHelper{ + public: - //checks for orientation: - // 0 - colinear - // 1 - clockwise - // 2 - counter clockwise - static int orientation(QPoint& p1, QPoint& p2, QPoint& p3); - //checks if q is on segment p1-p2 - static bool onSegment(QPoint& p1, QPoint& q, QPoint& p2); + static inline float sign(QPoint& p1, QPoint& p2, QPoint& p3){ + return (p1.x()-p3.x())*(p2.y()-p3.y())-(p2.x()-p3.x())*(p1.y()-p3.y()); + } - //cheks if p1-q1 intersects with p2-q2 - static bool hasIntersection(QPoint& p1, QPoint& q1, QPoint& p2, QPoint& q2); + + static inline bool isInTriangle(QPoint& A, QPoint& B, QPoint& C, QPoint& P){ + float val1, val2, val3; + bool neg, pos; + + val1 = IntelliHelper::sign(P,A,B); + val2 = IntelliHelper::sign(P,B,C); + val3 = IntelliHelper::sign(P,C,A); + + neg = (val1<0.f) || (val2<0.f) || (val3<0.f); + pos = (val1>0.f) || (val2>0.f) || (val3>0.f); + + return !(neg && pos); + } }; #endif diff --git a/src/Painting/Layer/PaintingArea.cpp b/src/Painting/Layer/PaintingArea.cpp index 58fc159..ac898f1 100644 --- a/src/Painting/Layer/PaintingArea.cpp +++ b/src/Painting/Layer/PaintingArea.cpp @@ -10,26 +10,18 @@ #include #include -#define EXPORT PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) :QWidget(parent){ this->setUp(maxWidth, maxHeight); - -#ifdef EXPORT - this->addLayer(maxWidth, maxHeight); - layerStructure[0].image->floodFill(QColor(255,255,255,255)); - activeLayer=0; -#endif -#ifndef EXPORT //tetsing this->addLayer(200,200,0,0,ImageType::Shaped_Image); layerStructure[0].image->floodFill(QColor(255,0,0,255)); std::vector polygon; - polygon.push_back(QPoint(100,0)); - polygon.push_back(QPoint(200,200)); - polygon.push_back(QPoint(0,200)); - polygon.push_back(QPoint(100,0)); + polygon.push_back(QPoint(100,000)); + polygon.push_back(QPoint(200,100)); + polygon.push_back(QPoint(100,200)); + polygon.push_back(QPoint(000,100)); layerStructure[0].image->setPolygon(polygon); this->addLayer(200,200,150,150); @@ -37,7 +29,6 @@ PaintingArea::PaintingArea(int maxWidth, int maxHeight, QWidget *parent) layerStructure[1].alpha=200; activeLayer=1; -#endif } void PaintingArea::setUp(int maxWidth, int maxHeight){ @@ -45,7 +36,6 @@ void PaintingArea::setUp(int maxWidth, int maxHeight){ this->maxWidth = maxWidth; this->maxHeight = maxHeight; Canvas = new QImage(maxWidth,maxHeight, QImage::Format_ARGB32); - Canvas->fill(Qt::GlobalColor::white); // Roots the widget to the top left even if resized setAttribute(Qt::WA_StaticContents); @@ -69,11 +59,11 @@ int PaintingArea::addLayer(int width, int height, int widthOffset, int heightOff } newLayer.alpha = 255; this->layerStructure.push_back(newLayer); - return layerStructure.size()-1; + return static_cast(layerStructure.size())-1; } void PaintingArea::deleteLayer(int index){ - if(index(layerStructure.size())){ this->layerStructure.erase(layerStructure.begin()+index); if(activeLayer>=index){ activeLayer--; @@ -82,26 +72,24 @@ void PaintingArea::deleteLayer(int index){ } void PaintingArea::deleteActiveLayer(){ + if(activeLayer>=0 && activeLayer < static_cast(layerStructure.size())){ this->layerStructure.erase(layerStructure.begin()+activeLayer); activeLayer--; + } } void PaintingArea::setLayerToActive(int index) { - if(index=0&&index(layerStructure.size())){ this->activeLayer=index; } } void PaintingArea::setAlphaToLayer(int index, int alpha){ - if(index=0&&index(layerStructure.size())){ + layerStructure[static_cast(index)].alpha=alpha; } } -QPixmap PaintingArea::getAsPixmap(){ - assembleLayers(); - return QPixmap::fromImage(*Canvas); -} // Used to load the image and place it in the widget bool PaintingArea::openImage(const QString &fileName) @@ -109,7 +97,7 @@ bool PaintingArea::openImage(const QString &fileName) if(this->activeLayer==-1){ return false; } - IntelliImage* active = layerStructure[activeLayer].image; + IntelliImage* active = layerStructure[static_cast(activeLayer)].image; bool open = active->loadImage(fileName); update(); return open; @@ -133,7 +121,6 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) } } - if (Canvas->save(fileName, fileFormat)) { return true; } else { @@ -144,13 +131,13 @@ bool PaintingArea::saveImage(const QString &fileName, const char *fileFormat) // Used to change the pen color void PaintingArea::setPenColor(const QColor &newColor) { - myPenColor = newColor; + //TODO give to Tool } // Used to change the pen width void PaintingArea::setPenWidth(int newWidth) { - myPenWidth = newWidth; + //TODO give to Tool } // Color the image area with white @@ -158,48 +145,50 @@ void PaintingArea::clearImage(int r, int g, int b){ if(this->activeLayer==-1){ return; } - IntelliImage* active = layerStructure[activeLayer].image; + IntelliImage* active = layerStructure[static_cast(activeLayer)].image; active->floodFill(QColor(r, g, b, 255)); update(); } void PaintingArea::activate(int a){ - this->setLayerToActive(a); + if(a>=0 && a < static_cast(layerStructure.size())){ + this->setLayerToActive(a); + } } void PaintingArea::setAlpha(int a){ if(activeLayer>=0){ - layerStructure[activeLayer].alpha=a; + layerStructure[static_cast(activeLayer)].alpha=a; } } void PaintingArea::getMoveUp(int a){ - layerStructure[activeLayer].heightOffset-=a; + layerStructure[static_cast(activeLayer)].heightOffset-=a; } void PaintingArea::getMoveDown(int a){ - layerStructure[activeLayer].heightOffset+=a; + layerStructure[static_cast(activeLayer)].heightOffset+=a; } void PaintingArea::getMoveRight(int a){ - layerStructure[activeLayer].widthOffset+=a; + layerStructure[static_cast(activeLayer)].widthOffset+=a; } void PaintingArea::getMoveLeft(int a){ - layerStructure[activeLayer].widthOffset-=a; + layerStructure[static_cast(activeLayer)].widthOffset-=a; } void PaintingArea::getMoveLayerUp(){ - if(activeLayer=0){ - std::swap(layerStructure[activeLayer], layerStructure[activeLayer+1]); + if(activeLayer(layerStructure.size()-1) && activeLayer>=0){ + std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer+1)]); activeLayer++; } } void PaintingArea::getMoveLayerDown(){ if(activeLayer>0){ - std::swap(layerStructure[activeLayer], layerStructure[activeLayer-1]); + std::swap(layerStructure[static_cast(activeLayer)], layerStructure[static_cast(activeLayer-1)]); activeLayer--; } } @@ -209,18 +198,7 @@ void PaintingArea::getMoveLayerDown(){ // Set that we are currently drawing void PaintingArea::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) { - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - //TODO CALCULATE LAST POINT - lastPoint=QPoint(x,y); - scribbling = true; - } + //TODO implement in tool } @@ -229,38 +207,13 @@ void PaintingArea::mousePressEvent(QMouseEvent *event) // from the last position to the current void PaintingArea::mouseMoveEvent(QMouseEvent *event) { - if ((event->buttons() & Qt::LeftButton) && scribbling){ - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - - //TODO CALCULATE NEW POINT - drawLineTo(QPoint(x,y)); - update(); - } + //TODO implement in Tool } // If the button is released we set variables to stop drawing void PaintingArea::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton && scribbling) { - if(this->activeLayer==-1){ - return; - } - LayerObject& active = layerStructure[activeLayer]; - - int x = event->x()-active.widthOffset; - int y = event->y()-active.heightOffset; - - //TODO CALCULATE NEW POINT - drawLineTo(QPoint(x,y)); - update(); - scribbling = false; - } + //TODO implement in tool } // QPainter provides functions to draw on the widget @@ -280,32 +233,17 @@ void PaintingArea::paintEvent(QPaintEvent *event) // to cut down on the need to resize the image void PaintingArea::resizeEvent(QResizeEvent *event) { - if(this->activeLayer==-1){ - return; - } - LayerObject active = layerStructure[activeLayer]; - - QPainter painter(this); - QRect dirtyRec(QPoint(0,0), event->size()); - painter.drawImage(dirtyRec, active.image->getDisplayable(event->size(), active.alpha), dirtyRec); + //TODO Doesnt quit work update(); } void PaintingArea::drawLineTo(const QPoint &endPoint) { - //// Used to draw on the widget - if(this->activeLayer==-1){ - return; - } - LayerObject active = layerStructure[activeLayer]; - active.image->drawLine(lastPoint, endPoint,myPenColor, myPenWidth); - lastPoint = endPoint; - update(); } void PaintingArea::resizeImage(QImage *image_res, const QSize &newSize){ - image_res->scaled(newSize,Qt::IgnoreAspectRatio); + //TODO implement } void PaintingArea::assembleLayers(bool forSaving){ @@ -321,13 +259,17 @@ void PaintingArea::assembleLayers(bool forSaving){ QColor clr_0; QColor clr_1; for(int y=0; y=maxHeight) break; for(int x=0; x=maxWidth) break; clr_0=Canvas->pixelColor(layer.widthOffset+x, layer.heightOffset+y); clr_1=cpy.pixelColor(x,y); - float t = (float)clr_1.alpha()/255.f; - int r =(float)clr_1.red()*(t)+(float)clr_0.red()*(1.-t); - int g =(float)clr_1.green()*(t)+(float)clr_0.green()*(1.-t); - int b =(float)clr_1.blue()*(t)+(float)clr_0.blue()*(1.-t); + float t = static_cast(clr_1.alpha())/255.f; + int r =static_cast(static_cast(clr_1.red())*(t)+static_cast(clr_0.red())*(1.f-t)+0.5f); + int g =static_cast(static_cast(clr_1.green())*(t)+static_cast(clr_0.green())*(1.f-t)+0.5f); + int b =static_cast(static_cast(clr_1.blue())*(t)+static_cast(clr_0.blue()*(1.f-t))+0.5f); int a =std::min(clr_0.alpha()+clr_1.alpha(), 255); clr_0.setRed(r); clr_0.setGreen(g); diff --git a/src/Painting/Layer/PaintingArea.h b/src/Painting/Layer/PaintingArea.h index febf33b..b8e172d 100644 --- a/src/Painting/Layer/PaintingArea.h +++ b/src/Painting/Layer/PaintingArea.h @@ -47,7 +47,6 @@ public: int penWidth() const { return myPenWidth; } - QPixmap getAsPixmap(); public slots: // Events to handle