From 223843f66554713ee926b09f958ff6bfdb5acb61 Mon Sep 17 00:00:00 2001 From: dirk Date: Mon, 14 Jul 2014 15:43:10 +0000 Subject: [PATCH] Added 'invert' option to the floodFill methods. --- Magick++/lib/Image.cpp | 209 +++++++++++++++++----------------- Magick++/lib/Magick++/Image.h | 36 +++--- Magick++/lib/Magick++/STL.h | 110 +++++++++--------- Magick++/lib/STL.cpp | 148 +++++++++++------------- 4 files changed, 247 insertions(+), 256 deletions(-) diff --git a/Magick++/lib/Image.cpp b/Magick++/lib/Image.cpp index 81f0bb693..8862736bc 100644 --- a/Magick++/lib/Image.cpp +++ b/Magick++/lib/Image.cpp @@ -1806,27 +1806,6 @@ void Magick::Image::alphaChannel(AlphaChannelOption alphaOption_) ThrowPPException; } -void Magick::Image::alphaFloodfill(const Color &target_, - const unsigned int alpha_,const ssize_t x_,const ssize_t y_, - const Magick::PaintMethod method_) -{ - PixelInfo - target; - - modifyImage(); - GetPixelInfo(constImage(),&target); - target.red=static_cast(target_).red; - target.green=static_cast(target_).green; - target.blue=static_cast(target_).blue; - target.alpha=alpha_; - GetPPException; - SetPPChannelMask(AlphaChannel); - FloodfillPaintImage(image(),options()->drawInfo(),&target,x_,y_, - method_ == FloodfillMethod ? MagickFalse : MagickTrue,exceptionInfo); - RestorePPChannelMask; - ThrowPPException; -} - void Magick::Image::annotate(const std::string &text_, const Geometry &location_) { @@ -2874,142 +2853,125 @@ void Magick::Image::flip(void) } void Magick::Image::floodFillAlpha(const ssize_t x_,const ssize_t y_, - const unsigned int alpha_,const PaintMethod method_) + const unsigned int alpha_,const bool invert_) { PixelInfo pixel, target; modifyImage(); - GetPixelInfo(image(),&target); + + GetPixelInfo(constImage(),&target); pixel=static_cast(pixelColor(x_,y_)); target.red=pixel.red; target.green=pixel.green; target.blue=pixel.blue; target.alpha=alpha_; + GetPPException; + SetPPChannelMask(AlphaChannel); + FloodfillPaintImage(image(),options()->drawInfo(),&target,x_,y_, + (MagickBooleanType)invert_,exceptionInfo); + RestorePPChannelMask; + ThrowPPException; +} + +void Magick::Image::floodFillAlpha(const ssize_t x_,const ssize_t y_, + const unsigned int alpha_,const Color &target_,const bool invert_) +{ + PixelInfo + pixel, + target; + + modifyImage(); + GetPixelInfo(constImage(),&target); + pixel=static_cast(target_); + target.red=pixel.red; + target.green=pixel.green; + target.blue=pixel.blue; + target.alpha=alpha_; GetPPException; - FloodfillPaintImage(image(),options()->drawInfo(),&target, - static_cast(x_), static_cast(y_), - method_ == FloodfillMethod ? MagickFalse : MagickTrue,exceptionInfo); + SetPPChannelMask(AlphaChannel); + FloodfillPaintImage(image(),options()->drawInfo(),&target,x_,y_, + (MagickBooleanType)invert_,exceptionInfo); + RestorePPChannelMask; ThrowPPException; } void Magick::Image::floodFillColor(const Geometry &point_, - const Magick::Color &fillColor_) + const Magick::Color &fillColor_,const bool invert_) { - floodFillTexture(point_,Image(Geometry(1,1),fillColor_)); + floodFillColor(point_.xOff(),point_.yOff(),fillColor_,invert_); } void Magick::Image::floodFillColor(const ssize_t x_,const ssize_t y_, - const Magick::Color &fillColor_) + const Magick::Color &fillColor_,const bool invert_) { - floodFillTexture(x_,y_,Image(Geometry(1,1),fillColor_)); + PixelInfo + pixel; + + modifyImage(); + + pixel=static_cast(pixelColor(x_,y_)); + floodFill(x_,y_,(Magick::Image *)NULL,fillColor_,&pixel,invert_); } void Magick::Image::floodFillColor(const Geometry &point_, - const Magick::Color &fillColor_,const Magick::Color &borderColor_) + const Magick::Color &fillColor_,const Magick::Color &borderColor_, + const bool invert_) { - floodFillTexture(point_,Image(Geometry(1,1),fillColor_),borderColor_); + floodFillColor(point_.xOff(),point_.yOff(),fillColor_,borderColor_,invert_); } void Magick::Image::floodFillColor(const ssize_t x_,const ssize_t y_, - const Magick::Color &fillColor_,const Magick::Color &borderColor_) + const Magick::Color &fillColor_,const Magick::Color &borderColor_, + const bool invert_) { - floodFillTexture(x_,y_,Image(Geometry(1,1),fillColor_),borderColor_); + PixelInfo + pixel; + + modifyImage(); + + pixel=static_cast(borderColor_); + floodFill(x_,y_,(Magick::Image *)NULL,fillColor_,&pixel,invert_); } void Magick::Image::floodFillTexture(const Magick::Geometry &point_, - const Magick::Image &texture_) + const Magick::Image &texture_,const bool invert_) { - floodFillTexture(point_.xOff(),point_.yOff(),texture_); + floodFillTexture(point_.xOff(),point_.yOff(),texture_,invert_); } void Magick::Image::floodFillTexture(const ssize_t x_,const ssize_t y_, - const Magick::Image &texture_) + const Magick::Image &texture_,const bool invert_) { - MagickCore::Image - *fillPattern; - - Quantum - *p; + PixelInfo + pixel; modifyImage(); - // Set drawing fill pattern - fillPattern=(MagickCore::Image *)NULL; - if (options()->fillPattern() != (MagickCore::Image *)NULL) - { - GetPPException; - fillPattern=CloneImage(options()->fillPattern(),0,0,MagickTrue, - exceptionInfo); - ThrowPPException; - } - options()->fillPattern(texture_.constImage()); - - // Get pixel view - Pixels pixels(*this); - // Fill image - p=pixels.get(x_,y_,1,1); - - if (p) - { - PixelInfo - target; - - GetPixelInfo(constImage(),&target); - target.red=GetPixelRed(constImage(),p); - target.green=GetPixelGreen(constImage(),p); - target.blue=GetPixelBlue(constImage(),p); - GetPPException; - FloodfillPaintImage(image(),options()->drawInfo(),&target, - static_cast(x_),static_cast(y_),MagickFalse, - exceptionInfo); - options()->fillPattern(fillPattern); - ThrowPPException; - } - else - options()->fillPattern(fillPattern); + pixel=static_cast(pixelColor(x_,y_)); + floodFill(x_,y_,&texture_,Magick::Color(),&pixel,invert_); } void Magick::Image::floodFillTexture(const Magick::Geometry &point_, - const Magick::Image &texture_,const Magick::Color &borderColor_) + const Magick::Image &texture_,const Magick::Color &borderColor_, + const bool invert_) { - floodFillTexture(point_.xOff(),point_.yOff(),texture_,borderColor_); + floodFillTexture(point_.xOff(),point_.yOff(),texture_,borderColor_,invert_); } void Magick::Image::floodFillTexture(const ssize_t x_,const ssize_t y_, - const Magick::Image &texture_,const Magick::Color &borderColor_) + const Magick::Image &texture_,const Magick::Color &borderColor_, + const bool invert_) { - MagickCore::Image - *fillPattern; - PixelInfo - target; + pixel; modifyImage(); - // Set drawing fill pattern - fillPattern=(MagickCore::Image *)NULL; - if (options()->fillPattern() != (MagickCore::Image *)NULL) - { - GetPPException; - fillPattern=CloneImage(options()->fillPattern(),0,0,MagickTrue, - exceptionInfo); - ThrowPPException; - } - options()->fillPattern(texture_.constImage()); - - GetPixelInfo(constImage(),&target); - target.red=static_cast(borderColor_).red; - target.green=static_cast(borderColor_).green; - target.blue=static_cast(borderColor_).blue; - GetPPException; - FloodfillPaintImage(image(),options()->drawInfo(),&target, - static_cast(x_),static_cast(y_),MagickTrue, - exceptionInfo); - options()->fillPattern(fillPattern); - ThrowPPException; + pixel=static_cast(borderColor_); + floodFill(x_,y_,&texture_,Magick::Color(),&pixel,invert_); } void Magick::Image::flop(void) @@ -5011,3 +4973,42 @@ void Magick::Image::unregisterId(void) modifyImage(); _imgRef->id(-1); } + +void Magick::Image::floodFill(const ssize_t x_,const ssize_t y_, + const Magick::Image *fillPattern_,const Magick::Color &fill_, + const MagickCore::PixelInfo *target_,const bool invert_) +{ + Magick::Color + fillColor; + + MagickCore::Image + *fillPattern; + + // Set drawing fill pattern or fill color + fillColor=options()->fillColor(); + fillPattern=(MagickCore::Image *)NULL; + if (options()->fillPattern() != (MagickCore::Image *)NULL) + { + GetPPException; + fillPattern=CloneImage(options()->fillPattern(),0,0,MagickTrue, + exceptionInfo); + ThrowPPException; + } + + if (fillPattern_ == (Magick::Image *)NULL) + { + options()->fillPattern((MagickCore::Image *)NULL); + options()->fillColor(fill_); + } + else + options()->fillPattern(fillPattern_->constImage()); + + GetPPException; + (void) FloodfillPaintImage(image(),options()->drawInfo(), + target_,static_cast(x_),static_cast(y_), + (MagickBooleanType) invert_,exceptionInfo); + + options()->fillColor(fillColor); + options()->fillPattern(fillPattern); + ThrowPPException; +} diff --git a/Magick++/lib/Magick++/Image.h b/Magick++/lib/Magick++/Image.h index 96668090f..994ed4763 100644 --- a/Magick++/lib/Magick++/Image.h +++ b/Magick++/lib/Magick++/Image.h @@ -594,10 +594,6 @@ namespace Magick // channel. void alphaChannel(AlphaChannelOption alphaOption_); - // Floodfill designated area with replacement alpha value - void alphaFloodfill(const Color &target_,const unsigned int alpha_, - const ::ssize_t x_, const ::ssize_t y_,const PaintMethod method_); - // // Annotate image (draw text on image) // @@ -889,39 +885,47 @@ namespace Magick void flip(void); // Floodfill pixels matching color (within fuzz factor) of target - // pixel(x,y) with replacement alpha value using method. + // pixel(x,y) with replacement alpha value. void floodFillAlpha(const ::ssize_t x_,const ::ssize_t y_, - const unsigned int alpha_,const PaintMethod method_); + const unsigned int alpha_,const bool invert_=false); + + // Floodfill designated area with replacement alpha value + void floodFillAlpha(const ssize_t x_,const ssize_t y_, + const unsigned int alpha_,const Color &target_,const bool invert_=false); // Flood-fill color across pixels that match the color of the // target pixel and are neighbors of the target pixel. // Uses current fuzz setting when determining color match. - void floodFillColor(const Geometry &point_,const Color &fillColor_); + void floodFillColor(const Geometry &point_,const Color &fillColor_, + const bool invert_=false); void floodFillColor(const ::ssize_t x_,const ::ssize_t y_, - const Color &fillColor_ ); + const Color &fillColor_,const bool invert_=false); // Flood-fill color across pixels starting at target-pixel and // stopping at pixels matching specified border color. // Uses current fuzz setting when determining color match. void floodFillColor(const Geometry &point_,const Color &fillColor_, - const Color &borderColor_); + const Color &borderColor_,const bool invert_=false); void floodFillColor(const ::ssize_t x_,const ::ssize_t y_, - const Color &fillColor_,const Color &borderColor_); + const Color &fillColor_,const Color &borderColor_, + const bool invert_=false); // Flood-fill texture across pixels that match the color of the // target pixel and are neighbors of the target pixel. // Uses current fuzz setting when determining color match. - void floodFillTexture(const Geometry &point_,const Image &texture_); + void floodFillTexture(const Geometry &point_,const Image &texture_, + const bool invert_=false); void floodFillTexture(const ::ssize_t x_,const ::ssize_t y_, - const Image &texture_); + const Image &texture_,const bool invert_=false); // Flood-fill texture across pixels starting at target-pixel and // stopping at pixels matching specified border color. // Uses current fuzz setting when determining color match. void floodFillTexture(const Geometry &point_,const Image &texture_, - const Color &borderColor_); + const Color &borderColor_,const bool invert_=false); void floodFillTexture(const ::ssize_t x_,const ::ssize_t y_, - const Image &texture_,const Color &borderColor_); + const Image &texture_,const Color &borderColor_, + const bool invert_=false); // Flop image (reflect each scanline in the horizontal direction) void flop(void); @@ -1486,6 +1490,10 @@ namespace Magick private: + void floodFill(const ssize_t x_,const ssize_t y_, + const Magick::Image *fillPattern_,const Color &fill_, + const PixelInfo *target,const bool invert_); + ImageRef *_imgRef; }; diff --git a/Magick++/lib/Magick++/STL.h b/Magick++/lib/Magick++/STL.h index 899ed99dd..43ac4728a 100644 --- a/Magick++/lib/Magick++/STL.h +++ b/Magick++/lib/Magick++/STL.h @@ -456,74 +456,87 @@ namespace Magick private: }; + // Floodfill designated area with a matte value + class MagickPPExport floodFillAlphaImage + : public std::unary_function + { + public: + floodFillAlphaImage(const ::ssize_t x_,const ::ssize_t y_, + const unsigned int alpha_,const Color &target_,const bool invert_=false); + + void operator()(Image &image_) const; + + private: + Color _target; + unsigned int _alpha; + ::ssize_t _x; + ::ssize_t _y; + bool _invert; + }; + // Flood-fill image with color - class MagickPPExport floodFillColorImage : public std::unary_function + class MagickPPExport floodFillColorImage + : public std::unary_function { public: // Flood-fill color across pixels starting at target-pixel and // stopping at pixels matching specified border color. // Uses current fuzz setting when determining color match. - floodFillColorImage( const ::ssize_t x_, - const ::ssize_t y_, - const Color &fillColor_ ); - - floodFillColorImage( const Geometry &point_, - const Color &fillColor_ ); + floodFillColorImage(const Geometry &point_,const Color &fillColor_, + const bool invert_=false); + floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_, + const Color &fillColor_,const bool invert_=false); // Flood-fill color across pixels starting at target-pixel and // stopping at pixels matching specified border color. // Uses current fuzz setting when determining color match. - floodFillColorImage( const ::ssize_t x_, - const ::ssize_t y_, - const Color &fillColor_, - const Color &borderColor_ ); + floodFillColorImage(const Geometry &point_,const Color &fillColor_, + const Color &borderColor_,const bool invert_=false); + floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_, + const Color &fillColor_,const Color &borderColor_, + const bool invert_=false); - floodFillColorImage( const Geometry &point_, - const Color &fillColor_, - const Color &borderColor_ ); - - void operator()( Image &image_ ) const; + void operator()(Image &image_) const; private: - ::ssize_t _x; - ::ssize_t _y; - Color _fillColor; - Color _borderColor; + ::ssize_t _x; + ::ssize_t _y; + Color _fillColor; + Color _borderColor; + bool _invert; }; // Flood-fill image with texture - class MagickPPExport floodFillTextureImage : public std::unary_function + class MagickPPExport floodFillTextureImage + : public std::unary_function { public: // Flood-fill texture across pixels that match the color of the // target pixel and are neighbors of the target pixel. // Uses current fuzz setting when determining color match. - floodFillTextureImage( const ::ssize_t x_, - const ::ssize_t y_, - const Image &texture_ ); - - floodFillTextureImage( const Geometry &point_, - const Image &texture_ ); + floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_, + const Image &texture_,const bool invert_=false); + floodFillTextureImage(const Geometry &point_,const Image &texture_, + const bool invert_=false); // Flood-fill texture across pixels starting at target-pixel and // stopping at pixels matching specified border color. // Uses current fuzz setting when determining color match. - floodFillTextureImage( const ::ssize_t x_, - const ::ssize_t y_, - const Image &texture_, - const Color &borderColor_ ); + floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_, + const Image &texture_,const Color &borderColor_, + const bool invert_=false); - floodFillTextureImage( const Geometry &point_, - const Image &texture_, - const Color &borderColor_ ); + floodFillTextureImage(const Geometry &point_,const Image &texture_, + const Color &borderColor_,const bool invert_=false); - void operator()( Image &image_ ) const; + void operator()(Image &image_) const; private: - ::ssize_t _x; - ::ssize_t _y; - Image _texture; - Color _borderColor; + ::ssize_t _x; + ::ssize_t _y; + Image _texture; + Color _borderColor; + bool _invert; }; // Flop image (reflect each scanline in the horizontal direction) @@ -693,25 +706,6 @@ namespace Magick bool _dither; }; - // Floodfill designated area with a matte value - class MagickPPExport alphaFloodfillImage : public std::unary_function - { - public: - alphaFloodfillImage( const Color &target_ , - const unsigned int alpha_, - const ::ssize_t x_, const ::ssize_t y_, - const PaintMethod method_ ); - - void operator()( Image &image_ ) const; - - private: - Color _target; - unsigned int _alpha; - ::ssize_t _x; - ::ssize_t _y; - PaintMethod _method; - }; - // Filter image by replacing each pixel component with the median // color in a circular neighborhood class MagickPPExport medianConvolveImage : public std::unary_function diff --git a/Magick++/lib/STL.cpp b/Magick++/lib/STL.cpp index e5e21be5e..3b86a69de 100644 --- a/Magick++/lib/STL.cpp +++ b/Magick++/lib/STL.cpp @@ -397,115 +397,120 @@ void Magick::flipImage::operator()( Magick::Image &image_ ) const image_.flip( ); } -// Flood-fill image with color -// Flood-fill color across pixels starting at target-pixel and -// stopping at pixels matching specified border color. Uses current -// fuzz setting when determining color match. -Magick::floodFillColorImage::floodFillColorImage( const ssize_t x_, - const ssize_t y_, - const Magick::Color &fillColor_ ) +Magick::floodFillAlphaImage::floodFillAlphaImage(const ssize_t x_, + const ssize_t y_,const unsigned int alpha_,const Color &target_, + const bool invert_) + : _target(target_), + _alpha(alpha_), + _x(x_), + _y(y_), + _invert(invert_) +{ +} + +void Magick::floodFillAlphaImage::operator()(Magick::Image &image_) const +{ + image_.floodFillAlpha(_x,_y,_alpha,_target,_invert); +} + +Magick::floodFillColorImage::floodFillColorImage(const ssize_t x_, + const ssize_t y_,const Magick::Color &fillColor_,const bool invert_) : _x(x_), _y(y_), _fillColor(fillColor_), - _borderColor() + _borderColor(), + _invert(invert_) { } -Magick::floodFillColorImage::floodFillColorImage( const Magick::Geometry &point_, - const Magick::Color &fillColor_ ) + +Magick::floodFillColorImage::floodFillColorImage( + const Magick::Geometry &point_,const Magick::Color &fillColor_, + const bool invert_) : _x(point_.xOff()), _y(point_.yOff()), _fillColor(fillColor_), - _borderColor() + _borderColor(), + _invert(invert_) { } -// Flood-fill color across pixels starting at target-pixel and -// stopping at pixels matching specified border color. Uses current -// fuzz setting when determining color match. -Magick::floodFillColorImage::floodFillColorImage( const ssize_t x_, - const ssize_t y_, - const Magick::Color &fillColor_, - const Magick::Color &borderColor_ ) + +Magick::floodFillColorImage::floodFillColorImage(const ssize_t x_, + const ssize_t y_,const Magick::Color &fillColor_, + const Magick::Color &borderColor_,const bool invert_) : _x(x_), _y(y_), _fillColor(fillColor_), - _borderColor(borderColor_) + _borderColor(borderColor_), + _invert(invert_) { } -Magick::floodFillColorImage::floodFillColorImage( const Geometry &point_, - const Color &fillColor_, - const Color &borderColor_ ) + +Magick::floodFillColorImage::floodFillColorImage(const Geometry &point_, + const Color &fillColor_,const Color &borderColor_,const bool invert_) : _x(point_.xOff()), _y(point_.yOff()), _fillColor(fillColor_), - _borderColor(borderColor_) + _borderColor(borderColor_), + _invert(invert_) { } -void Magick::floodFillColorImage::operator()( Magick::Image &image_ ) const +void Magick::floodFillColorImage::operator()(Magick::Image &image_) const { - if ( _borderColor.isValid() ) - { - image_.floodFillColor( _x, _y, _fillColor, _borderColor ); - } + if (_borderColor.isValid()) + image_.floodFillColor(_x,_y,_fillColor,_borderColor,_invert); else - { - image_.floodFillColor( _x, _y, _fillColor ); - } + image_.floodFillColor(_x,_y,_fillColor,_invert); } -// Flood-fill image with texture - -// Flood-fill texture across pixels that match the color of the target -// pixel and are neighbors of the target pixel. Uses current fuzz -// setting when determining color match. -Magick::floodFillTextureImage::floodFillTextureImage( const ssize_t x_, - const ssize_t y_, - const Magick::Image &texture_ ) +Magick::floodFillTextureImage::floodFillTextureImage(const ssize_t x_, + const ssize_t y_,const Magick::Image &texture_,const bool invert_) : _x(x_), _y(y_), _texture(texture_), - _borderColor() + _borderColor(), + _invert(invert_) { } -Magick::floodFillTextureImage::floodFillTextureImage( const Magick::Geometry &point_, - const Magick::Image &texture_ ) + +Magick::floodFillTextureImage::floodFillTextureImage( + const Magick::Geometry &point_,const Magick::Image &texture_, + const bool invert_) : _x(point_.xOff()), _y(point_.yOff()), _texture(texture_), - _borderColor() + _borderColor(), + _invert(invert_) { } -// Flood-fill texture across pixels starting at target-pixel and -// stopping at pixels matching specified border color. Uses current -// fuzz setting when determining color match. -Magick::floodFillTextureImage::floodFillTextureImage( const ssize_t x_, - const ssize_t y_, - const Magick::Image &texture_, - const Magick::Color &borderColor_ ) + +Magick::floodFillTextureImage::floodFillTextureImage(const ssize_t x_, + const ssize_t y_,const Magick::Image &texture_, + const Magick::Color &borderColor_,const bool invert_) : _x(x_), _y(y_), _texture(texture_), - _borderColor(borderColor_) + _borderColor(borderColor_), + _invert(invert_) { } -Magick::floodFillTextureImage::floodFillTextureImage( const Magick::Geometry &point_, - const Magick::Image &texture_, - const Magick::Color &borderColor_ ) + +Magick::floodFillTextureImage::floodFillTextureImage( + const Magick::Geometry &point_,const Magick::Image &texture_, + const Magick::Color &borderColor_,const bool invert_) : _x(point_.xOff()), _y(point_.yOff()), _texture(texture_), - _borderColor(borderColor_) + _borderColor(borderColor_), + _invert(invert_) { } -void Magick::floodFillTextureImage::operator()( Magick::Image &image_ ) const + +void Magick::floodFillTextureImage::operator()(Magick::Image &image_) const { - if ( _borderColor.isValid() ) - { - image_.floodFillTexture( _x, _y, _texture, _borderColor ); - } + if (_borderColor.isValid()) + image_.floodFillTexture(_x,_y,_texture,_borderColor,_invert); else - { - image_.floodFillTexture( _x, _y, _texture ); - } + image_.floodFillTexture(_x,_y,_texture,_invert); } // Flop image (reflect each scanline in the horizontal direction) @@ -660,23 +665,6 @@ void Magick::mapImage::operator()( Magick::Image &image_ ) const image_.map( _mapImage, _dither ); } -// Floodfill designated area with a matte value -Magick::alphaFloodfillImage::alphaFloodfillImage( const Color &target_ , - const unsigned int alpha_, - const ssize_t x_, const ssize_t y_, - const PaintMethod method_ ) - : _target( target_ ), - _alpha( alpha_ ), - _x( x_ ), - _y( y_ ), - _method( method_ ) -{ -} -void Magick::alphaFloodfillImage::operator()( Magick::Image &image_ ) const -{ - image_.alphaFloodfill( _target, _alpha, _x, _y, _method ); -} - // Filter image by replacing each pixel component with the median // color in a circular neighborhood Magick::medianConvolveImage::medianConvolveImage( const double radius_ ) -- 2.40.0