// This may look like C code, but it is really -*- C++ -*- // // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003 // // Copyright @ 2013 ImageMagick Studio LLC, a non-profit organization // dedicated to making software imaging solutions freely available. // // Definition and implementation of template functions for using // Magick::Image with STL containers. // #ifndef Magick_STL_header #define Magick_STL_header #include "Magick++/Include.h" #include #include #include #include #include #include "Magick++/CoderInfo.h" #include "Magick++/Drawable.h" #include "Magick++/Exception.h" #include "Magick++/Montage.h" namespace Magick { // // STL function object declarations/definitions // // Function objects provide the means to invoke an operation on one // or more image objects in an STL-compatable container. The // arguments to the function object constructor(s) are compatable // with the arguments to the equivalent Image class method and // provide the means to supply these options when the function // object is invoked. // For example, to read a GIF animation, set the color red to // transparent for all frames, and write back out: // // list images; // readImages( &images, "animation.gif" ); // for_each( images.begin(), images.end(), transparentImage( "red" ) ); // writeImages( images.begin(), images.end(), "animation.gif" ); // Adaptive-blur image with specified blur factor class MagickPPExport adaptiveBlurImage { public: adaptiveBlurImage( const double radius_ = 1, const double sigma_ = 0.5 ); void operator()( Image &image_ ) const; private: double _radius; double _sigma; }; // Local adaptive threshold image // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm // Width x height define the size of the pixel neighborhood // offset = constant to subtract from pixel neighborhood mean class MagickPPExport adaptiveThresholdImage { public: adaptiveThresholdImage( const size_t width_, const size_t height_, const ::ssize_t offset_ = 0 ); void operator()( Image &image_ ) const; private: size_t _width; size_t _height; ::ssize_t _offset; }; // Add noise to image with specified noise type class MagickPPExport addNoiseImage { public: addNoiseImage(const NoiseType noiseType_,const double attenuate_ = 1.0); void operator()(Image &image_) const; private: NoiseType _noiseType; double _attenuate; }; // Transform image by specified affine (or free transform) matrix. class MagickPPExport affineTransformImage { public: affineTransformImage( const DrawableAffine &affine_ ); void operator()( Image &image_ ) const; private: DrawableAffine _affine; }; // Annotate image (draw text on image) class MagickPPExport annotateImage { public: // Annotate using specified text, and placement location annotateImage ( const std::string &text_, const Geometry &geometry_ ); // Annotate using specified text, bounding area, and placement // gravity annotateImage ( const std::string &text_, const Geometry &geometry_, const GravityType gravity_ ); // Annotate with text using specified text, bounding area, // placement gravity, and rotation. annotateImage ( const std::string &text_, const Geometry &geometry_, const GravityType gravity_, const double degrees_ ); // Annotate with text (bounding area is entire image) and // placement gravity. annotateImage ( const std::string &text_, const GravityType gravity_ ); void operator()( Image &image_ ) const; private: const std::string _text; const Geometry _geometry; const GravityType _gravity; const double _degrees; }; // Blur image with specified blur factor class MagickPPExport blurImage { public: blurImage( const double radius_ = 1, const double sigma_ = 0.5 ); void operator()( Image &image_ ) const; private: double _radius; double _sigma; }; // Border image (add border to image) class MagickPPExport borderImage { public: borderImage( const Geometry &geometry_ = borderGeometryDefault ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Extract channel from image class MagickPPExport channelImage { public: channelImage( const ChannelType channel_ ); void operator()( Image &image_ ) const; private: ChannelType _channel; }; // Charcoal effect image (looks like charcoal sketch) class MagickPPExport charcoalImage { public: charcoalImage( const double radius_ = 1, const double sigma_ = 0.5 ); void operator()( Image &image_ ) const; private: double _radius; double _sigma; }; // Chop image (remove vertical or horizontal subregion of image) class MagickPPExport chopImage { public: chopImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Accepts a lightweight Color Correction Collection (CCC) file which solely // contains one or more color corrections and applies the correction to the // image. class MagickPPExport cdlImage { public: cdlImage( const std::string &cdl_ ); void operator()( Image &image_ ) const; private: std::string _cdl; }; // Colorize image using pen color at specified percent alpha class MagickPPExport colorizeImage { public: colorizeImage( const unsigned int alphaRed_, const unsigned int alphaGreen_, const unsigned int alphaBlue_, const Color &penColor_ ); colorizeImage( const unsigned int alpha_, const Color &penColor_ ); void operator()( Image &image_ ) const; private: unsigned int _alphaRed; unsigned int _alphaGreen; unsigned int _alphaBlue; Color _penColor; }; // Apply a color matrix to the image channels. The user supplied // matrix may be of order 1 to 5 (1x1 through 5x5). class MagickPPExport colorMatrixImage { public: colorMatrixImage( const size_t order_, const double *color_matrix_ ); void operator()( Image &image_ ) const; private: size_t _order; const double *_color_matrix; }; // Convert the image colorspace representation class MagickPPExport colorSpaceImage { public: colorSpaceImage( ColorspaceType colorSpace_ ); void operator()( Image &image_ ) const; private: ColorspaceType _colorSpace; }; // Comment image (add comment string to image) class MagickPPExport commentImage { public: commentImage( const std::string &comment_ ); void operator()( Image &image_ ) const; private: std::string _comment; }; // Compose an image onto another at specified offset and using // specified algorithm class MagickPPExport compositeImage { public: compositeImage( const Image &compositeImage_, ::ssize_t xOffset_, ::ssize_t yOffset_, CompositeOperator compose_ = InCompositeOp ); compositeImage( const Image &compositeImage_, const Geometry &offset_, CompositeOperator compose_ = InCompositeOp ); void operator()( Image &image_ ) const; private: Image _compositeImage; ::ssize_t _xOffset; ::ssize_t _yOffset; CompositeOperator _compose; }; // Contrast image (enhance intensity differences in image) class MagickPPExport contrastImage { public: contrastImage( const size_t sharpen_ ); void operator()( Image &image_ ) const; private: size_t _sharpen; }; // Crop image (subregion of original image) class MagickPPExport cropImage { public: cropImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Cycle image colormap class MagickPPExport cycleColormapImage { public: cycleColormapImage( const ::ssize_t amount_ ); void operator()( Image &image_ ) const; private: ::ssize_t _amount; }; // Despeckle image (reduce speckle noise) class MagickPPExport despeckleImage { public: despeckleImage( void ); void operator()( Image &image_ ) const; private: }; // Distort image. distorts an image using various distortion methods, by // mapping color lookups of the source image to a new destination image // usually of the same size as the source image, unless 'bestfit' is set to // true. class MagickPPExport distortImage { public: distortImage( const Magick::DistortMethod method_, const size_t number_arguments_, const double *arguments_, const bool bestfit_ ); distortImage( const Magick::DistortMethod method_, const size_t number_arguments_, const double *arguments_ ); void operator()( Image &image_ ) const; private: DistortMethod _method; size_t _number_arguments; const double *_arguments; bool _bestfit; }; // Draw on image class MagickPPExport drawImage { public: // Draw on image using a single drawable // Store in list to make implementation easier drawImage( const Drawable &drawable_ ); // Draw on image using a drawable list drawImage( const DrawableList &drawable_ ); void operator()( Image &image_ ) const; private: DrawableList _drawableList; }; // Edge image (highlight edges in image) class MagickPPExport edgeImage { public: edgeImage( const double radius_ = 0.0 ); void operator()( Image &image_ ) const; private: double _radius; }; // Emboss image (highlight edges with 3D effect) class MagickPPExport embossImage { public: embossImage( void ); embossImage( const double radius_, const double sigma_ ); void operator()( Image &image_ ) const; private: double _radius; double _sigma; }; // Enhance image (minimize noise) class MagickPPExport enhanceImage { public: enhanceImage( void ); void operator()( Image &image_ ) const; private: }; // Equalize image (histogram equalization) class MagickPPExport equalizeImage { public: equalizeImage( void ); void operator()( Image &image_ ) const; private: }; // Color to use when filling drawn objects class MagickPPExport fillColorImage { public: fillColorImage( const Color &fillColor_ ); void operator()( Image &image_ ) const; private: Color _fillColor; }; // Flip image (reflect each scanline in the vertical direction) class MagickPPExport flipImage { public: flipImage( void ); void operator()( Image &image_ ) const; private: }; // Floodfill designated area with a matte value class MagickPPExport floodFillAlphaImage { 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: // 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 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 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); void operator()(Image &image_) const; private: ::ssize_t _x; ::ssize_t _y; Color _fillColor; Color _borderColor; bool _invert; }; // Flood-fill image with texture class MagickPPExport floodFillTextureImage { 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_,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_, const bool invert_=false); floodFillTextureImage(const Geometry &point_,const Image &texture_, const Color &borderColor_,const bool invert_=false); void operator()(Image &image_) const; private: ::ssize_t _x; ::ssize_t _y; Image _texture; Color _borderColor; bool _invert; }; // Flop image (reflect each scanline in the horizontal direction) class MagickPPExport flopImage { public: flopImage( void ); void operator()( Image &image_ ) const; private: }; // Frame image class MagickPPExport frameImage { public: frameImage( const Geometry &geometry_ = frameGeometryDefault ); frameImage( const size_t width_, const size_t height_, const ::ssize_t innerBevel_ = 6, const ::ssize_t outerBevel_ = 6 ); void operator()( Image &image_ ) const; private: size_t _width; size_t _height; ::ssize_t _outerBevel; ::ssize_t _innerBevel; }; // Gamma correct image class MagickPPExport gammaImage { public: gammaImage( const double gamma_ ); gammaImage ( const double gammaRed_, const double gammaGreen_, const double gammaBlue_ ); void operator()( Image &image_ ) const; private: double _gammaRed; double _gammaGreen; double _gammaBlue; }; // Gaussian blur image // The number of neighbor pixels to be included in the convolution // mask is specified by 'width_'. The standard deviation of the // gaussian bell curve is specified by 'sigma_'. class MagickPPExport gaussianBlurImage { public: gaussianBlurImage( const double width_, const double sigma_ ); void operator()( Image &image_ ) const; private: double _width; double _sigma; }; // Apply a color lookup table (Hald CLUT) to the image. class MagickPPExport haldClutImage { public: haldClutImage( const Image &haldClutImage_ ); void operator()( Image &image_ ) const; private: Image _haldClutImage; }; // Implode image (special effect) class MagickPPExport implodeImage { public: implodeImage( const double factor_ = 50 ); void operator()( Image &image_ ) const; private: double _factor; }; // implements the inverse discrete Fourier transform (IFT) of the image // either as a magnitude / phase or real / imaginary image pair. class MagickPPExport inverseFourierTransformImage { public: inverseFourierTransformImage( const Image &phaseImage_ ); void operator()( Image &image_ ) const; private: Image _phaseImage; }; // Set image validity. Valid images become empty (inValid) if // argument is false. class MagickPPExport isValidImage { public: isValidImage( const bool isValid_ ); void operator()( Image &image_ ) const; private: bool _isValid; }; // Label image class MagickPPExport labelImage { public: labelImage( const std::string &label_ ); void operator()( Image &image_ ) const; private: std::string _label; }; // Level image class MagickPPExport levelImage { public: levelImage( const double black_point, const double white_point, const double mid_point=1.0 ); void operator()( Image &image_ ) const; private: double _black_point; double _white_point; double _mid_point; }; // Magnify image by integral size class MagickPPExport magnifyImage { public: magnifyImage( void ); void operator()( Image &image_ ) const; private: }; // Remap image colors with closest color from reference image class MagickPPExport mapImage { public: mapImage( const Image &mapImage_ , const bool dither_ = false ); void operator()( Image &image_ ) const; private: Image _mapImage; bool _dither; }; // Filter image by replacing each pixel component with the median // color in a circular neighborhood class MagickPPExport medianConvolveImage { public: medianConvolveImage( const double radius_ = 0.0 ); void operator()( Image &image_ ) const; private: double _radius; }; // Merge image layers class MagickPPExport mergeLayersImage { public: mergeLayersImage ( LayerMethod layerMethod_ ); void operator()( Image &image_ ) const; private: LayerMethod _layerMethod; }; // Reduce image by integral size class MagickPPExport minifyImage { public: minifyImage( void ); void operator()( Image &image_ ) const; private: }; // Modulate percent hue, saturation, and brightness of an image class MagickPPExport modulateImage { public: modulateImage( const double brightness_, const double saturation_, const double hue_ ); void operator()( Image &image_ ) const; private: double _brightness; double _saturation; double _hue; }; // Negate colors in image. Set grayscale to only negate grayscale // values in image. class MagickPPExport negateImage { public: negateImage( const bool grayscale_ = false ); void operator()( Image &image_ ) const; private: bool _grayscale; }; // Normalize image (increase contrast by normalizing the pixel // values to span the full range of color values) class MagickPPExport normalizeImage { public: normalizeImage( void ); void operator()( Image &image_ ) const; private: }; // Oilpaint image (image looks like oil painting) class MagickPPExport oilPaintImage { public: oilPaintImage( const double radius_ = 3 ); void operator()( Image &image_ ) const; private: double _radius; }; // Set or attenuate the image alpha channel. If the image pixels // are opaque then they are set to the specified alpha value, // otherwise they are blended with the supplied alpha value. The // value of alpha_ ranges from 0 (completely opaque) to // QuantumRange. The defines OpaqueAlpha and TransparentAlpha are // available to specify completely opaque or completely transparent, // respectively. class MagickPPExport alphaImage { public: alphaImage( const unsigned int alpha_ ); void operator()( Image &image_ ) const; private: unsigned int _alpha; }; // Change color of opaque pixel to specified pen color. class MagickPPExport opaqueImage { public: opaqueImage( const Color &opaqueColor_, const Color &penColor_ ); void operator()( Image &image_ ) const; private: Color _opaqueColor; Color _penColor; }; // Quantize image (reduce number of colors) class MagickPPExport quantizeImage { public: quantizeImage( const bool measureError_ = false ); void operator()( Image &image_ ) const; private: bool _measureError; }; // Raise image (lighten or darken the edges of an image to give a // 3-D raised or lowered effect) class MagickPPExport raiseImage { public: raiseImage( const Geometry &geometry_ = raiseGeometryDefault, const bool raisedFlag_ = false ); void operator()( Image &image_ ) const; private: Geometry _geometry; bool _raisedFlag; }; class MagickPPExport ReadOptions { public: // Default constructor ReadOptions(void); // Copy constructor ReadOptions(const ReadOptions& options_); // Destructor ~ReadOptions(); // Vertical and horizontal resolution in pixels of the image void density(const Geometry &geometry_); Geometry density(void) const; // Image depth (8 or 16) void depth(size_t depth_); size_t depth(void) const; // Ping the image instead of reading it void ping(const bool flag_); bool ping(void) const; // Suppress all warning messages. Error messages are still reported. void quiet(const bool quiet_); bool quiet(void) const; // Image size (required for raw formats) void size(const Geometry &geometry_); Geometry size(void) const; // // Internal implementation methods. Please do not use. // MagickCore::ImageInfo *imageInfo(void); private: // Assignment not supported ReadOptions& operator=(const ReadOptions&); MagickCore::ImageInfo *_imageInfo; bool _quiet; }; // Reduce noise in image using a noise peak elimination filter class MagickPPExport reduceNoiseImage { public: reduceNoiseImage( void ); reduceNoiseImage (const size_t order_ ); void operator()( Image &image_ ) const; private: size_t _order; }; // Resize image to specified size. class MagickPPExport resizeImage { public: resizeImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Roll image (rolls image vertically and horizontally) by specified // number of columns and rows) class MagickPPExport rollImage { public: rollImage( const Geometry &roll_ ); rollImage( const ::ssize_t columns_, const ::ssize_t rows_ ); void operator()( Image &image_ ) const; private: ssize_t _columns; ssize_t _rows; }; // Rotate image counter-clockwise by specified number of degrees. class MagickPPExport rotateImage { public: rotateImage( const double degrees_ ); void operator()( Image &image_ ) const; private: double _degrees; }; // Resize image by using pixel sampling algorithm class MagickPPExport sampleImage { public: sampleImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Resize image by using simple ratio algorithm class MagickPPExport scaleImage { public: scaleImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Segment (coalesce similar image components) by analyzing the // histograms of the color components and identifying units that are // homogeneous with the fuzzy c-means technique. // Also uses QuantizeColorSpace and Verbose image attributes class MagickPPExport segmentImage { public: segmentImage( const double clusterThreshold_ = 1.0, const double smoothingThreshold_ = 1.5 ); void operator()( Image &image_ ) const; private: double _clusterThreshold; double _smoothingThreshold; }; // Shade image using distant light source class MagickPPExport shadeImage { public: shadeImage( const double azimuth_ = 30, const double elevation_ = 30, const bool colorShading_ = false ); void operator()( Image &image_ ) const; private: double _azimuth; double _elevation; bool _colorShading; }; // Shadow effect image (simulate an image shadow) class MagickPPExport shadowImage { public: shadowImage( const double percent_opacity_ = 80, const double sigma_ = 0.5, const ssize_t x_ = 5, const ssize_t y_ = 5 ); void operator()( Image &image_ ) const; private: double _percent_opacity; double _sigma; ssize_t _x; ssize_t _y; }; // Sharpen pixels in image class MagickPPExport sharpenImage { public: sharpenImage( const double radius_ = 1, const double sigma_ = 0.5 ); void operator()( Image &image_ ) const; private: double _radius; double _sigma; }; // Shave pixels from image edges. class MagickPPExport shaveImage { public: shaveImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Shear image (create parallelogram by sliding image by X or Y axis) class MagickPPExport shearImage { public: shearImage( const double xShearAngle_, const double yShearAngle_ ); void operator()( Image &image_ ) const; private: double _xShearAngle; double _yShearAngle; }; // Solarize image (similar to effect seen when exposing a // photographic film to light during the development process) class MagickPPExport solarizeImage { public: solarizeImage( const double factor_ ); void operator()( Image &image_ ) const; private: double _factor; }; // Splice the background color into the image. class MagickPPExport spliceImage { public: spliceImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // Spread pixels randomly within image by specified amount class MagickPPExport spreadImage { public: spreadImage( const size_t amount_ = 3 ); void operator()( Image &image_ ) const; private: size_t _amount; }; // Add a digital watermark to the image (based on second image) class MagickPPExport steganoImage { public: steganoImage( const Image &waterMark_ ); void operator()( Image &image_ ) const; private: Image _waterMark; }; // Create an image which appears in stereo when viewed with red-blue glasses // (Red image on left, blue on right) class MagickPPExport stereoImage { public: stereoImage( const Image &rightImage_ ); void operator()( Image &image_ ) const; private: Image _rightImage; }; // Color to use when drawing object outlines class MagickPPExport strokeColorImage { public: strokeColorImage( const Color &strokeColor_ ); void operator()( Image &image_ ) const; private: Color _strokeColor; }; // Swirl image (image pixels are rotated by degrees) class MagickPPExport swirlImage { public: swirlImage( const double degrees_ ); void operator()( Image &image_ ) const; private: double _degrees; }; // Channel a texture on image background class MagickPPExport textureImage { public: textureImage( const Image &texture_ ); void operator()( Image &image_ ) const; private: Image _texture; }; // Threshold image class MagickPPExport thresholdImage { public: thresholdImage( const double threshold_ ); void operator()( Image &image_ ) const; private: double _threshold; }; // Set image color to transparent class MagickPPExport transparentImage { public: transparentImage( const Color& color_ ); void operator()( Image &image_ ) const; private: Color _color; }; // Trim edges that are the background color from the image class MagickPPExport trimImage { public: trimImage( void ); void operator()( Image &image_ ) const; private: }; // Map image pixels to a sine wave class MagickPPExport waveImage { public: waveImage( const double amplitude_ = 25.0, const double wavelength_ = 150.0 ); void operator()( Image &image_ ) const; private: double _amplitude; double _wavelength; }; // Zoom image to specified size. class MagickPPExport zoomImage { public: zoomImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // // Function object image attribute accessors // // Join images into a single multi-image file class MagickPPExport adjoinImage { public: adjoinImage( const bool flag_ ); void operator()( Image &image_ ) const; private: bool _flag; }; // Time in 1/100ths of a second which must expire before displaying // the next image in an animated sequence. class MagickPPExport animationDelayImage { public: animationDelayImage( const size_t delay_ ); void operator()( Image &image_ ) const; private: size_t _delay; }; // Number of iterations to loop an animation (e.g. Netscape loop // extension) for. class MagickPPExport animationIterationsImage { public: animationIterationsImage( const size_t iterations_ ); void operator()( Image &image_ ) const; private: size_t _iterations; }; // Image background color class MagickPPExport backgroundColorImage { public: backgroundColorImage( const Color &color_ ); void operator()( Image &image_ ) const; private: Color _color; }; // Name of texture image to tile onto the image background class MagickPPExport backgroundTextureImage { public: backgroundTextureImage( const std::string &backgroundTexture_ ); void operator()( Image &image_ ) const; private: std::string _backgroundTexture; }; // Image border color class MagickPPExport borderColorImage { public: borderColorImage( const Color &color_ ); void operator()( Image &image_ ) const; private: Color _color; }; // Text bounding-box base color (default none) class MagickPPExport boxColorImage { public: boxColorImage( const Color &boxColor_ ); void operator()( Image &image_ ) const; private: Color _boxColor; }; // Chromaticity blue primary point. class MagickPPExport chromaBluePrimaryImage { public: chromaBluePrimaryImage(const double x_,const double y_,const double z_); void operator()(Image &image_) const; private: double _x; double _y; double _z; }; // Chromaticity green primary point. class MagickPPExport chromaGreenPrimaryImage { public: chromaGreenPrimaryImage(const double x_,const double y_,const double z_); void operator()(Image &image_) const; private: double _x; double _y; double _z; }; // Chromaticity red primary point. class MagickPPExport chromaRedPrimaryImage { public: chromaRedPrimaryImage(const double x_,const double y_,const double z_); void operator()(Image &image_) const; private: double _x; double _y; double _z; }; // Chromaticity white point. class MagickPPExport chromaWhitePointImage { public: chromaWhitePointImage(const double x_,const double y_,const double z_); void operator()(Image &image_) const; private: double _x; double _y; double _z; }; // Colors within this distance are considered equal class MagickPPExport colorFuzzImage { public: colorFuzzImage( const double fuzz_ ); void operator()( Image &image_ ) const; private: double _fuzz; }; // Color at colormap position index_ class MagickPPExport colorMapImage { public: colorMapImage( const size_t index_, const Color &color_ ); void operator()( Image &image_ ) const; private: size_t _index; Color _color; }; // Composition operator to be used when composition is implicitly used // (such as for image flattening). class MagickPPExport composeImage { public: composeImage( const CompositeOperator compose_ ); void operator()( Image &image_ ) const; private: CompositeOperator _compose; }; // Compression type class MagickPPExport compressTypeImage { public: compressTypeImage( const CompressionType compressType_ ); void operator()( Image &image_ ) const; private: CompressionType _compressType; }; // Vertical and horizontal resolution in pixels of the image class MagickPPExport densityImage { public: densityImage( const Point &point_ ); void operator()( Image &image_ ) const; private: Point _point; }; // Image depth (bits allocated to red/green/blue components) class MagickPPExport depthImage { public: depthImage( const size_t depth_ ); void operator()( Image &image_ ) const; private: size_t _depth; }; // Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image // formats which support endian-specific options. class MagickPPExport endianImage { public: endianImage( const EndianType endian_ ); void operator()( Image &image_ ) const; private: EndianType _endian; }; // Image file name class MagickPPExport fileNameImage { public: fileNameImage( const std::string &fileName_ ); void operator()( Image &image_ ) const; private: std::string _fileName; }; // Filter to use when resizing image class MagickPPExport filterTypeImage { public: filterTypeImage( const FilterType filterType_ ); void operator()( Image &image_ ) const; private: FilterType _filterType; }; // Text rendering font class MagickPPExport fontImage { public: fontImage( const std::string &font_ ); void operator()( Image &image_ ) const; private: std::string _font; }; // Font point size class MagickPPExport fontPointsizeImage { public: fontPointsizeImage( const size_t pointsize_ ); void operator()( Image &image_ ) const; private: size_t _pointsize; }; // GIF disposal method class MagickPPExport gifDisposeMethodImage { public: gifDisposeMethodImage( const DisposeType disposeMethod_ ); void operator()( Image &image_ ) const; private: DisposeType _disposeMethod; }; // Type of interlacing to use class MagickPPExport interlaceTypeImage { public: interlaceTypeImage( const InterlaceType interlace_ ); void operator()( Image &image_ ) const; private: InterlaceType _interlace; }; // File type magick identifier (.e.g "GIF") class MagickPPExport magickImage { public: magickImage( const std::string &magick_ ); void operator()( Image &image_ ) const; private: std::string _magick; }; // Image supports transparent color class MagickPPExport alphaFlagImage { public: alphaFlagImage( const bool alphaFlag_ ); void operator()( Image &image_ ) const; private: bool _alphaFlag; }; // Transparent color class MagickPPExport matteColorImage { public: matteColorImage( const Color &matteColor_ ); void operator()( Image &image_ ) const; private: Color _matteColor; }; // Indicate that image is black and white class MagickPPExport monochromeImage { public: monochromeImage( const bool monochromeFlag_ ); void operator()( Image &image_ ) const; private: bool _monochromeFlag; }; // Pen color class MagickPPExport penColorImage { public: penColorImage( const Color &penColor_ ); void operator()( Image &image_ ) const; private: Color _penColor; }; // Pen texture image. class MagickPPExport penTextureImage { public: penTextureImage( const Image &penTexture_ ); void operator()( Image &image_ ) const; private: Image _penTexture; }; // Set pixel color at location x & y. class MagickPPExport pixelColorImage { public: pixelColorImage( const ::ssize_t x_, const ::ssize_t y_, const Color &color_); void operator()( Image &image_ ) const; private: ::ssize_t _x; ::ssize_t _y; Color _color; }; // Postscript page size. class MagickPPExport pageImage { public: pageImage( const Geometry &pageSize_ ); void operator()( Image &image_ ) const; private: Geometry _pageSize; }; // JPEG/MIFF/PNG compression level (default 75). class MagickPPExport qualityImage { public: qualityImage( const size_t quality_ ); void operator()( Image &image_ ) const; private: size_t _quality; }; // Maximum number of colors to quantize to class MagickPPExport quantizeColorsImage { public: quantizeColorsImage( const size_t colors_ ); void operator()( Image &image_ ) const; private: size_t _colors; }; // Colorspace to quantize in. class MagickPPExport quantizeColorSpaceImage { public: quantizeColorSpaceImage( const ColorspaceType colorSpace_ ); void operator()( Image &image_ ) const; private: ColorspaceType _colorSpace; }; // Dither image during quantization (default true). class MagickPPExport quantizeDitherImage { public: quantizeDitherImage( const bool ditherFlag_ ); void operator()( Image &image_ ) const; private: bool _ditherFlag; }; // Quantization tree-depth class MagickPPExport quantizeTreeDepthImage { public: quantizeTreeDepthImage( const size_t treeDepth_ ); void operator()( Image &image_ ) const; private: size_t _treeDepth; }; // The type of rendering intent class MagickPPExport renderingIntentImage { public: renderingIntentImage( const RenderingIntent renderingIntent_ ); void operator()( Image &image_ ) const; private: RenderingIntent _renderingIntent; }; // Units of image resolution class MagickPPExport resolutionUnitsImage { public: resolutionUnitsImage( const ResolutionType resolutionUnits_ ); void operator()( Image &image_ ) const; private: ResolutionType _resolutionUnits; }; // Image scene number class MagickPPExport sceneImage { public: sceneImage( const size_t scene_ ); void operator()( Image &image_ ) const; private: size_t _scene; }; // adjust the image contrast with a non-linear sigmoidal contrast algorithm class MagickPPExport sigmoidalContrastImage { public: sigmoidalContrastImage( const size_t sharpen_, const double contrast, const double midpoint = (double) QuantumRange / 2.0 ); void operator()( Image &image_ ) const; private: size_t _sharpen; double contrast; double midpoint; }; // Width and height of a raw image class MagickPPExport sizeImage { public: sizeImage( const Geometry &geometry_ ); void operator()( Image &image_ ) const; private: Geometry _geometry; }; // stripImage strips an image of all profiles and comments. class MagickPPExport stripImage { public: stripImage( void ); void operator()( Image &image_ ) const; private: }; // Subimage of an image sequence class MagickPPExport subImageImage { public: subImageImage( const size_t subImage_ ); void operator()( Image &image_ ) const; private: size_t _subImage; }; // Number of images relative to the base image class MagickPPExport subRangeImage { public: subRangeImage( const size_t subRange_ ); void operator()( Image &image_ ) const; private: size_t _subRange; }; // Anti-alias Postscript and TrueType fonts (default true) class MagickPPExport textAntiAliasImage { public: textAntiAliasImage( const bool flag_ ); void operator()( Image &image_ ) const; private: bool _flag; }; // Image storage type class MagickPPExport typeImage { public: typeImage( const ImageType type_ ); void operator()( Image &image_ ) const; private: Magick::ImageType _type; }; // Print detailed information about the image class MagickPPExport verboseImage { public: verboseImage( const bool verbose_ ); void operator()( Image &image_ ) const; private: bool _verbose; }; // X11 display to display to, obtain fonts from, or to capture // image from class MagickPPExport x11DisplayImage { public: x11DisplayImage( const std::string &display_ ); void operator()( Image &image_ ) const; private: std::string _display; }; ////////////////////////////////////////////////////////// // // Implementation template definitions. Not for end-use. // ////////////////////////////////////////////////////////// // Changes the channel mask of the images and places the old // values in the container. template void channelMaskImages(InputIterator first_,InputIterator last_, Container *container_,const ChannelType channel_) { MagickCore::ChannelType channel_mask; container_->clear(); for (InputIterator iter = first_; iter != last_; ++iter) { iter->modifyImage(); channel_mask=MagickCore::SetImageChannelMask(iter->image(),channel_); container_->push_back(channel_mask); } } // Insert images in image list into existing container (appending to container) // The images should not be deleted since only the image ownership is passed. // The options are copied into the object. template void insertImages(Container *sequence_,MagickCore::Image* images_) { MagickCore::Image *image, *next; image=images_; while (image != (MagickCore::Image *) NULL) { next=image->next; image->next=(MagickCore::Image *) NULL; if (next != (MagickCore::Image *) NULL) next->previous=(MagickCore::Image *) NULL; sequence_->push_back(Magick::Image(image)); image=next; } } // Link images together into an image list based on the ordering of // the container implied by the iterator. This step is done in // preparation for use with ImageMagick functions which operate on // lists of images. // Images are selected by range, first_ to last_ so that a subset of // the container may be selected. Specify first_ via the // container's begin() method and last_ via the container's end() // method in order to specify the entire container. template bool linkImages(InputIterator first_,InputIterator last_) { MagickCore::Image *current, *previous; ::ssize_t scene; scene=0; previous=(MagickCore::Image *) NULL; for (InputIterator iter = first_; iter != last_; ++iter) { // Unless we reduce the reference count to one, the same image // structure may occur more than once in the container, causing // the linked list to fail. iter->modifyImage(); current=iter->image(); current->previous=previous; current->next=(MagickCore::Image *) NULL; current->scene=(size_t) scene++; if (previous != (MagickCore::Image *) NULL) previous->next=current; previous=current; } return(scene > 0 ? true : false); } // Restores the channel mask of the images. template void restoreChannelMaskImages(InputIterator first_,InputIterator last_, Container *container_) { typename Container::iterator channel_mask; channel_mask=container_->begin(); for (InputIterator iter = first_; iter != last_; ++iter) { iter->modifyImage(); (void) MagickCore::SetImageChannelMask(iter->image(), (const MagickCore::ChannelType) *channel_mask); channel_mask++; } } // Remove links added by linkImages. This should be called after the // ImageMagick function call has completed to reset the image list // back to its pristine un-linked state. template void unlinkImages(InputIterator first_,InputIterator last_) { MagickCore::Image *image; for (InputIterator iter = first_; iter != last_; ++iter) { image=iter->image(); image->previous=(MagickCore::Image *) NULL; image->next=(MagickCore::Image *) NULL; } } /////////////////////////////////////////////////////////////////// // // Template definitions for documented API // /////////////////////////////////////////////////////////////////// template void animateImages( InputIterator first_,InputIterator last_) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::AnimateImages(first_->imageInfo(),first_->image(), exceptionInfo); unlinkImages(first_,last_); ThrowPPException(first_->quiet()); } // Append images from list into single image in either horizontal or // vertical direction. template void appendImages( Image *appendedImage_, InputIterator first_, InputIterator last_, bool stack_ = false) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = MagickCore::AppendImages( first_->image(), (MagickBooleanType) stack_, exceptionInfo ); unlinkImages( first_, last_ ); appendedImage_->replaceImage( image ); ThrowPPException(appendedImage_->quiet()); } // Adds the names of the artifacts of the image to the container. template void artifactNames(Container *names_,const Image* image_) { const char* name; names_->clear(); MagickCore::ResetImageArtifactIterator(image_->constImage()); name=MagickCore::GetNextImageArtifact(image_->constImage()); while (name != (const char *) NULL) { names_->push_back(std::string(name)); name=MagickCore::GetNextImageArtifact(image_->constImage()); } } // Adds the names of the attributes of the image to the container. template void attributeNames(Container *names_,const Image* image_) { const char* name; names_->clear(); MagickCore::ResetImagePropertyIterator(image_->constImage()); name=MagickCore::GetNextImageProperty(image_->constImage()); while (name != (const char *) NULL) { names_->push_back(std::string(name)); name=MagickCore::GetNextImageProperty(image_->constImage()); } } // Average a set of images. // All the input images must be the same size in pixels. template void averageImages( Image *averagedImage_, InputIterator first_, InputIterator last_ ) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = MagickCore::EvaluateImages( first_->image(), MagickCore::MeanEvaluateOperator, exceptionInfo ); unlinkImages( first_, last_ ); averagedImage_->replaceImage( image ); ThrowPPException(averagedImage_->quiet()); } // Merge a sequence of images. // This is useful for GIF animation sequences that have page // offsets and disposal methods. A container to contain // the updated image sequence is passed via the coalescedImages_ // option. template void coalesceImages(Container *coalescedImages_,InputIterator first_, InputIterator last_) { bool quiet; MagickCore::Image *images; if (linkImages(first_,last_) == false) return; GetPPException; quiet=first_->quiet(); images=MagickCore::CoalesceImages(first_->image(),exceptionInfo); // Unlink image list unlinkImages(first_,last_); // Ensure container is empty coalescedImages_->clear(); // Move images to container insertImages(coalescedImages_,images); // Report any error ThrowPPException(quiet); } // Return format coders matching specified conditions. // // The default (if no match terms are supplied) is to return all // available format coders. // // For example, to return all readable formats: // list coderList; // coderInfoList( &coderList, CoderInfo::TrueMatch, CoderInfo::AnyMatch, CoderInfo::AnyMatch) // template void coderInfoList( Container *container_, CoderInfo::MatchType isReadable_ = CoderInfo::AnyMatch, CoderInfo::MatchType isWritable_ = CoderInfo::AnyMatch, CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch ) { // Obtain first entry in MagickInfo list size_t number_formats; GetPPException; char **coder_list = MagickCore::GetMagickList( "*", &number_formats, exceptionInfo ); if( !coder_list ) { throwException(exceptionInfo); throwExceptionExplicit(MagickCore::MissingDelegateError, "Coder array not returned!", 0 ); } // Clear out container container_->clear(); for ( ::ssize_t i=0; i < (::ssize_t) number_formats; i++) { const MagickCore::MagickInfo *magick_info = MagickCore::GetMagickInfo( coder_list[i], exceptionInfo ); if (!magick_info) continue; coder_list[i]=(char *) MagickCore::RelinquishMagickMemory( coder_list[i] ); // Skip stealth coders if ( MagickCore::GetMagickStealth(magick_info) ) continue; try { CoderInfo coderInfo( magick_info->name ); // Test isReadable_ if ( isReadable_ != CoderInfo::AnyMatch && (( coderInfo.isReadable() && isReadable_ != CoderInfo::TrueMatch ) || ( !coderInfo.isReadable() && isReadable_ != CoderInfo::FalseMatch )) ) continue; // Test isWritable_ if ( isWritable_ != CoderInfo::AnyMatch && (( coderInfo.isWritable() && isWritable_ != CoderInfo::TrueMatch ) || ( !coderInfo.isWritable() && isWritable_ != CoderInfo::FalseMatch )) ) continue; // Test isMultiFrame_ if ( isMultiFrame_ != CoderInfo::AnyMatch && (( coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) || ( !coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) ) continue; // Append matches to container container_->push_back( coderInfo ); } // Intentionally ignore missing module errors catch (Magick::ErrorModule&) { continue; } } coder_list=(char **) MagickCore::RelinquishMagickMemory( coder_list ); ThrowPPException(false); } // // Fill container with color histogram. // Entries are of type "std::pair". Use the pair // "first" member to access the Color and the "second" member to access // the number of times the color occurs in the image. // // For example: // // Using : // // Image image("image.miff"); // map histogram; // colorHistogram( &histogram, image ); // std::map::const_iterator p=histogram.begin(); // while (p != histogram.end()) // { // cout << setw(10) << (int)p->second << ": (" // << setw(quantum_width) << (int)p->first.redQuantum() << "," // << setw(quantum_width) << (int)p->first.greenQuantum() << "," // << setw(quantum_width) << (int)p->first.blueQuantum() << ")" // << endl; // p++; // } // // Using : // // Image image("image.miff"); // std::vector > histogram; // colorHistogram( &histogram, image ); // std::vector >::const_iterator p=histogram.begin(); // while (p != histogram.end()) // { // cout << setw(10) << (int)p->second << ": (" // << setw(quantum_width) << (int)p->first.redQuantum() << "," // << setw(quantum_width) << (int)p->first.greenQuantum() << "," // << setw(quantum_width) << (int)p->first.blueQuantum() << ")" // << endl; // p++; // } template void colorHistogram( Container *histogram_, const Image image) { GetPPException; // Obtain histogram array size_t colors; MagickCore::PixelInfo *histogram_array = MagickCore::GetImageHistogram( image.constImage(), &colors, exceptionInfo ); ThrowPPException(image.quiet()); // Clear out container histogram_->clear(); // Transfer histogram array to container for ( size_t i=0; i < colors; i++) { histogram_->insert( histogram_->end(), std::pair ( Color(histogram_array[i]), (size_t) histogram_array[i].count) ); } // Deallocate histogram array histogram_array=(MagickCore::PixelInfo *) MagickCore::RelinquishMagickMemory(histogram_array); } // Combines one or more images into a single image. The grayscale value of // the pixels of each image in the sequence is assigned in order to the // specified channels of the combined image. The typical ordering would be // image 1 => Red, 2 => Green, 3 => Blue, etc. template void combineImages(Image *combinedImage_,InputIterator first_, InputIterator last_,const ChannelType channel_, const ColorspaceType colorspace_ = MagickCore::sRGBColorspace) { MagickCore::Image *image; std::vector channelMask; if (linkImages(first_,last_) == false) return; GetPPException; channelMaskImages(first_,last_,&channelMask,channel_); image=CombineImages(first_->image(),colorspace_,exceptionInfo); restoreChannelMaskImages(first_,last_,&channelMask); unlinkImages(first_,last_); combinedImage_->replaceImage(image); ThrowPPException(combinedImage_->quiet()); } template void cropToTiles(Container *tiledImages_,const Image image_, const Geometry &geometry_) { GetPPException; MagickCore::Image* images=CropImageToTiles(image_.constImage(), static_cast(geometry_).c_str(),exceptionInfo); tiledImages_->clear(); insertImages(tiledImages_,images); ThrowPPException(image_.quiet()); } // Break down an image sequence into constituent parts. This is // useful for creating GIF or MNG animation sequences. template void deconstructImages(Container *deconstructedImages_, InputIterator first_,InputIterator last_) { bool quiet; MagickCore::Image *images; if (linkImages(first_,last_) == false) return; GetPPException; quiet=first_->quiet(); images=CompareImagesLayers(first_->image(),CompareAnyLayer,exceptionInfo); unlinkImages(first_,last_); deconstructedImages_->clear(); insertImages(deconstructedImages_,images); ThrowPPException(quiet); } // // Display an image sequence // template void displayImages(InputIterator first_,InputIterator last_) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::DisplayImages(first_->imageInfo(),first_->image(), exceptionInfo); unlinkImages(first_,last_); ThrowPPException(first_->quiet()); } // Applies a value to the image with an arithmetic, relational, // or logical operator to an image. Use these operations to lighten or darken // an image, to increase or decrease contrast in an image, or to produce the // "negative" of an image. template void evaluateImages( Image *evaluatedImage_, InputIterator first_, InputIterator last_, const MagickEvaluateOperator operator_ ) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = EvaluateImages( first_->image(), operator_, exceptionInfo ); unlinkImages( first_, last_ ); evaluatedImage_->replaceImage( image ); ThrowPPException(evaluatedImage_->quiet()); } // Merge a sequence of image frames which represent image layers. // This is useful for combining Photoshop layers into a single image. template void flattenImages( Image *flattenedImage_, InputIterator first_, InputIterator last_ ) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(), FlattenLayer,exceptionInfo ); unlinkImages( first_, last_ ); flattenedImage_->replaceImage( image ); ThrowPPException(flattenedImage_->quiet()); } // Implements the discrete Fourier transform (DFT) of the image either as a // magnitude / phase or real / imaginary image pair. template void forwardFourierTransformImage( Container *fourierImages_, const Image &image_ ) { GetPPException; // Build image list MagickCore::Image* images = ForwardFourierTransformImage( image_.constImage(), MagickTrue, exceptionInfo); // Ensure container is empty fourierImages_->clear(); // Move images to container insertImages( fourierImages_, images ); // Report any error ThrowPPException(image_.quiet()); } template void forwardFourierTransformImage( Container *fourierImages_, const Image &image_, const bool magnitude_ ) { GetPPException; // Build image list MagickCore::Image* images = ForwardFourierTransformImage( image_.constImage(), magnitude_ == true ? MagickTrue : MagickFalse, exceptionInfo); // Ensure container is empty fourierImages_->clear(); // Move images to container insertImages( fourierImages_, images ); // Report any error ThrowPPException(image_.quiet()); } // Applies a mathematical expression to a sequence of images. template void fxImages(Image *fxImage_,InputIterator first_,InputIterator last_, const std::string expression) { MagickCore::Image *image; if (linkImages(first_,last_) == false) return; GetPPException; image=FxImage(first_->constImage(),expression.c_str(),exceptionInfo); unlinkImages(first_,last_); fxImage_->replaceImage(image); ThrowPPException(fxImage_->quiet()); } // Replace the colors of a sequence of images with the closest color // from a reference image. // Set dither_ to true to enable dithering. Set measureError_ to // true in order to evaluate quantization error. template void mapImages(InputIterator first_,InputIterator last_, const Image& mapImage_,bool dither_=false,bool measureError_=false) { MagickCore::Image *image; MagickCore::QuantizeInfo quantizeInfo; if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::GetQuantizeInfo(&quantizeInfo); quantizeInfo.dither_method = dither_ ? MagickCore::RiemersmaDitherMethod : MagickCore::NoDitherMethod; MagickCore::RemapImages(&quantizeInfo,first_->image(), (mapImage_.isValid() ? mapImage_.constImage() : (const MagickCore::Image*) NULL),exceptionInfo); unlinkImages(first_,last_); if (exceptionInfo->severity != MagickCore::UndefinedException) { unlinkImages(first_,last_); throwException(exceptionInfo,mapImage_.quiet()); } image=first_->image(); while(image != (MagickCore::Image *) NULL) { // Calculate quantization error if (measureError_) { MagickCore::GetImageQuantizeError(image,exceptionInfo); if (exceptionInfo->severity > MagickCore::UndefinedException) { unlinkImages(first_,last_); throwException(exceptionInfo,mapImage_.quiet()); } } // Update DirectClass representation of pixels MagickCore::SyncImage(image,exceptionInfo); if (exceptionInfo->severity > MagickCore::UndefinedException) { unlinkImages(first_,last_); throwException(exceptionInfo,mapImage_.quiet()); } // Next image image=image->next; } unlinkImages(first_,last_); (void) MagickCore::DestroyExceptionInfo(exceptionInfo); } // Composes all the image layers from the current given // image onward to produce a single image of the merged layers. template void mergeImageLayers( Image *mergedImage_, InputIterator first_, InputIterator last_, const LayerMethod method_ ) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = MergeImageLayers( first_->image(), method_, exceptionInfo ); unlinkImages( first_, last_ ); mergedImage_->replaceImage( image ); ThrowPPException(mergedImage_->quiet()); } // Create a composite image by combining several separate images. template void montageImages(Container *montageImages_,InputIterator first_, InputIterator last_,const Montage &options_) { bool quiet; MagickCore::Image *images; MagickCore::MontageInfo *montageInfo; if (linkImages(first_,last_) == false) return; montageInfo=static_cast( MagickCore::AcquireMagickMemory(sizeof(MagickCore::MontageInfo))); // Update montage options with those set in montageOpts_ options_.updateMontageInfo(*montageInfo); // Update options which must transfer to image options if (options_.label().length() != 0) first_->label(options_.label()); // Do montage GetPPException; quiet=first_->quiet(); images=MagickCore::MontageImages(first_->image(),montageInfo, exceptionInfo); // Unlink linked image list unlinkImages(first_,last_); // Reset output container to pristine state montageImages_->clear(); if (images != (MagickCore::Image *) NULL) insertImages(montageImages_,images); // Clean up any allocated data in montageInfo MagickCore::DestroyMontageInfo(montageInfo); // Report any montage error ThrowPPException(quiet); // Apply transparency to montage images if (montageImages_->size() > 0 && options_.transparentColor().isValid()) for_each(montageImages_->begin(),montageImages_->end(),transparentImage( options_.transparentColor())); } // Morph a set of images template void morphImages(Container *morphedImages_,InputIterator first_, InputIterator last_,size_t frames_) { bool quiet; MagickCore::Image *images; if (linkImages(first_,last_) == false) return; GetPPException; quiet=first_->quiet(); images=MagickCore::MorphImages(first_->image(),frames_,exceptionInfo); // Unlink image list unlinkImages(first_,last_); // Ensure container is empty morphedImages_->clear(); // Move images to container insertImages(morphedImages_,images); // Report any error ThrowPPException(quiet); } // Inlay a number of images to form a single coherent picture. template void mosaicImages( Image *mosaicImage_, InputIterator first_, InputIterator last_ ) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(), MosaicLayer,exceptionInfo ); unlinkImages( first_, last_ ); mosaicImage_->replaceImage( image ); ThrowPPException(mosaicImage_->quiet()); } // Compares each image the GIF disposed forms of the previous image in // the sequence. From this it attempts to select the smallest cropped // image to replace each frame, while preserving the results of the // GIF animation. template void optimizeImageLayers(Container *optimizedImages_,InputIterator first_, InputIterator last_) { bool quiet; MagickCore::Image *images; if (linkImages(first_,last_) == false) return; GetPPException; quiet=first_->quiet(); images=OptimizeImageLayers(first_->image(),exceptionInfo); unlinkImages(first_,last_); optimizedImages_->clear(); insertImages(optimizedImages_,images); ThrowPPException(quiet); } // optimizeImagePlusLayers is exactly as optimizeImageLayers, but may // also add or even remove extra frames in the animation, if it improves // the total number of pixels in the resulting GIF animation. template void optimizePlusImageLayers(Container *optimizedImages_, InputIterator first_,InputIterator last_ ) { bool quiet; MagickCore::Image *images; if (linkImages(first_,last_) == false) return; GetPPException; quiet=first_->quiet(); images=OptimizePlusImageLayers(first_->image(),exceptionInfo); unlinkImages(first_,last_); optimizedImages_->clear(); insertImages(optimizedImages_,images); ThrowPPException(quiet); } // Compares each image the GIF disposed forms of the previous image in the // sequence. Any pixel that does not change the displayed result is replaced // with transparency. template void optimizeTransparency(InputIterator first_,InputIterator last_) { if (linkImages(first_,last_) == false) return; GetPPException; OptimizeImageTransparency(first_->image(),exceptionInfo); unlinkImages(first_,last_ ); ThrowPPException(first_->quiet()); } // Ping images into existing container (appending to container) template void pingImages(Container *sequence_,const std::string &imageSpec_, ReadOptions &options) { options.ping(true); readImages(sequence_,imageSpec_,options); } template void pingImages(Container *sequence_,const std::string &imageSpec_) { ReadOptions options; pingImages(sequence_,imageSpec_,options); } template void pingImages(Container *sequence_,const Blob &blob_,ReadOptions &options) { options.ping(true); readImages(sequence_,blob_,options); } template void pingImages(Container *sequence_,const Blob &blob_) { ReadOptions options; pingImages(sequence_,blob_,options); } // Adds the names of the profiles of the image to the container. template void profileNames(Container *names_,const Image* image_) { const char* name; names_->clear(); MagickCore::ResetImageProfileIterator(image_->constImage()); name=MagickCore::GetNextImageProfile(image_->constImage()); while (name != (const char *) NULL) { names_->push_back(std::string(name)); name=MagickCore::GetNextImageProfile(image_->constImage()); } } // Quantize colors in images using current quantization settings // Set measureError_ to true in order to measure quantization error template void quantizeImages(InputIterator first_,InputIterator last_, bool measureError_ = false) { if (linkImages(first_,last_) == false) return; GetPPException; MagickCore::QuantizeImages(first_->quantizeInfo(),first_->image(), exceptionInfo); unlinkImages(first_,last_); MagickCore::Image *image=first_->image(); while (image != (MagickCore::Image *) NULL) { // Calculate quantization error if (measureError_) MagickCore::GetImageQuantizeError(image,exceptionInfo); // Update DirectClass representation of pixels MagickCore::SyncImage(image,exceptionInfo); image=image->next; } unlinkImages(first_,last_); ThrowPPException(first_->quiet()); } // Read images into existing container (appending to container) template void readImages(Container *sequence_,const std::string &imageSpec_, ReadOptions &options) { MagickCore::Image *images; MagickCore::ImageInfo *imageInfo; imageInfo=options.imageInfo(); imageSpec_.copy(imageInfo->filename,MagickPathExtent-1); imageInfo->filename[imageSpec_.length()] = 0; GetPPException; images=MagickCore::ReadImage(imageInfo,exceptionInfo); insertImages(sequence_,images); ThrowPPException(options.quiet()); } template void readImages(Container *sequence_,const std::string &imageSpec_) { ReadOptions options; readImages(sequence_,imageSpec_,options); } template void readImages(Container *sequence_,const Blob &blob_,ReadOptions &options) { MagickCore::Image *images; GetPPException; images=MagickCore::BlobToImage(options.imageInfo(),blob_.data(), blob_.length(),exceptionInfo); insertImages(sequence_,images); ThrowPPException(options.quiet()); } template void readImages(Container *sequence_,const Blob &blob_) { ReadOptions options; readImages(sequence_,blob_,options); } // Returns a separate grayscale image for each channel specified. template void separateImages(Container *separatedImages_,Image &image_, const ChannelType channel_) { MagickCore::ChannelType channel_mask; MagickCore::Image *images; GetPPException; channel_mask=MagickCore::SetImageChannelMask(image_.image(),channel_); images=SeparateImages(image_.constImage(),exceptionInfo); MagickCore::SetPixelChannelMask(image_.image(),channel_mask); separatedImages_->clear(); insertImages(separatedImages_,images); ThrowPPException(image_.quiet()); } // Smush images from list into single image in either horizontal or // vertical direction. template void smushImages(Image *smushedImage_,InputIterator first_, InputIterator last_,const ssize_t offset_,bool stack_=false) { MagickCore::Image *newImage; if (linkImages(first_,last_) == false) return; GetPPException; newImage=MagickCore::SmushImages(first_->constImage(), (MagickBooleanType) stack_,offset_,exceptionInfo); unlinkImages(first_,last_); smushedImage_->replaceImage(newImage); ThrowPPException(smushedImage_->quiet()); } // Write Images template void writeImages( InputIterator first_, InputIterator last_, const std::string &imageSpec_, bool adjoin_ = true ) { if (linkImages(first_,last_) == false) return; first_->adjoin( adjoin_ ); GetPPException; ::ssize_t errorStat = MagickCore::WriteImages( first_->constImageInfo(), first_->image(), imageSpec_.c_str(), exceptionInfo ); unlinkImages( first_, last_ ); if ( errorStat != false ) { (void) MagickCore::DestroyExceptionInfo( exceptionInfo ); return; } ThrowPPException(first_->quiet()); } // Write images to BLOB template void writeImages( InputIterator first_, InputIterator last_, Blob *blob_, bool adjoin_ = true) { if (linkImages(first_,last_) == false) return; first_->adjoin( adjoin_ ); GetPPException; size_t length = 2048; // Efficient size for small images void* data = MagickCore::ImagesToBlob( first_->imageInfo(), first_->image(), &length, exceptionInfo); blob_->updateNoCopy( data, length, Magick::Blob::MallocAllocator ); unlinkImages( first_, last_ ); ThrowPPException(first_->quiet()); } } // namespace Magick #endif // Magick_STL_header