void FillTool::fillMaskLine(int x, int y) { if ((x >= 0) && (x < m_image.width()) && (y >= 0) && (y < m_image.height())) { if (m_mask.pixelIndex(x, y) == 0) { if (rgbDistance(m_image.pixel(x, y), m_oldRgb) < FILL_THRESHOLD) { int x1, x2; x1 = x - 1; x2 = x + 1; while ((x1 >= 0) && (rgbDistance(m_image.pixel(x1, y), m_oldRgb) < FILL_THRESHOLD)) { x1--; } while ((x2 < m_image.width()) && (rgbDistance(m_image.pixel(x2, y), m_oldRgb) < FILL_THRESHOLD)) { x2++; } for (int i = x1 + 1; i < x2; i++) { m_mask.setPixel(i, y, 1); } for (int i = x1 + 1; i < x2; i++) { fillMaskLine(i, y - 1); } for (int i = x1 + 1; i < x2; i++) { fillMaskLine(i, y + 1); } } } } }
void BitmapImage::floodFill(BitmapImage* targetImage, BitmapImage* fillImage, QPoint point, QRgb targetColour, QRgb replacementColour, int tolerance, bool extendFillImage) { QList<QPoint> queue; // queue all the pixels of the filled area (as they are found) int j, k; bool condition; BitmapImage* replaceImage; if (extendFillImage) { replaceImage = new BitmapImage(targetImage->mBounds.united(fillImage->mBounds), QColor(0,0,0,0)); } else { targetImage->extend(fillImage->mBounds); // not necessary - here just to prevent some bug when we draw outside the targetImage - to be fixed replaceImage = new BitmapImage(fillImage->mBounds, QColor(0,0,0,0)); replaceImage->mExtendable = false; } //QPainter painter1(replaceImage->image); //QPainter painter2(fillImage->image); //painter1.setPen( QColor(replacementColour) ); QPen myPen; myPen = QPen( QColor(replacementColour) , 1.0, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin); targetColour = targetImage->pixel(point.x(), point.y()); //if ( rgbDistance(targetImage->pixel(point.x(), point.y()), targetColour) > tolerance ) return; queue.append( point ); // ----- flood fill // ----- from the standard flood fill algorithm // ----- http://en.wikipedia.org/wiki/Flood_fill j = -1; k = 1; for(int i=0; i< queue.size(); i++ ) { point = queue.at(i); if ( replaceImage->pixel(point.x(), point.y()) != replacementColour && rgbDistance(targetImage->pixel(point.x(), point.y()), targetColour) < tolerance ) { j = -1; condition = (point.x() + j > targetImage->left()); if (!extendFillImage) condition = condition && (point.x() + j > replaceImage->left()); while ( replaceImage->pixel(point.x()+j, point.y()) != replacementColour && rgbDistance(targetImage->pixel( point.x()+j, point.y() ), targetColour) < tolerance && condition) { j = j - 1; condition = (point.x() + j > targetImage->left()); if (!extendFillImage) condition = condition && (point.x() + j > replaceImage->left()); } k = 1; condition = ( point.x() + k < targetImage->right()-1); if (!extendFillImage) condition = condition && (point.x() + k < replaceImage->right()-1); while ( replaceImage->pixel(point.x()+k, point.y()) != replacementColour && rgbDistance(targetImage->pixel( point.x()+k, point.y() ), targetColour) < tolerance && condition) { k = k + 1; condition = ( point.x() + k < targetImage->right()-1); if (!extendFillImage) condition = condition && (point.x() + k < replaceImage->right()-1); } //painter1.drawLine( point.x()+j, point.y(), point.x()+k+1, point.y() ); replaceImage->drawLine( QPointF(point.x()+j, point.y()), QPointF(point.x()+k, point.y()), myPen, QPainter::CompositionMode_SourceOver, false); //for(int l=0; l<=k-j+1 ; l++) { // replaceImage->setPixel( point.x()+j, point.y(), replacementColour ); //} for(int x = j+1; x < k; x++) { //replaceImage->setPixel( point.x()+x, point.y(), replacementColour); condition = point.y() - 1 > targetImage->top(); if (!extendFillImage) condition = condition && (point.y() - 1 > replaceImage->top()); if ( condition && queue.size() < targetImage->height() * targetImage->width() ) { if ( replaceImage->pixel(point.x()+x, point.y()-1) != replacementColour) { if (rgbDistance(targetImage->pixel( point.x()+x, point.y() - 1), targetColour) < tolerance) { queue.append( point + QPoint(x,-1) ); } else { replaceImage->setPixel( point.x()+x, point.y()-1, replacementColour); } } } condition = point.y() + 1 < targetImage->bottom(); if (!extendFillImage) condition = condition && (point.y() + 1 < replaceImage->bottom()); if ( condition && queue.size() < targetImage->height() * targetImage->width() ) { if ( replaceImage->pixel(point.x()+x, point.y()+1) != replacementColour) { if (rgbDistance(targetImage->pixel( point.x()+x, point.y() + 1), targetColour) < tolerance) { queue.append( point + QPoint(x, 1) ); } else { replaceImage->setPixel( point.x()+x, point.y()+1, replacementColour); } } } } } } //painter2.drawImage( QPoint(0,0), *replaceImage ); //bool memo = fillImage->mExtendable; //fillImage->mExtendable = false; fillImage->paste(replaceImage); //fillImage->mExtendable = memo; //replaceImage->fill(qRgba(0,0,0,0)); //painter1.end(); //painter2.end(); delete replaceImage; //update(); }