From: dirk Date: Sun, 16 Mar 2014 11:49:24 +0000 (+0000) Subject: Added orderedDither, selectiveBlur, separate, sepiaTone, sketch, smushImages, tint... X-Git-Tag: 7.0.1-0~2576 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f1775d8f60a3ce551a096140d7559d46ba33ac14;p=imagemagick Added orderedDither, selectiveBlur, separate, sepiaTone, sketch, smushImages, tint, uniqueColors and vignette to Magick++. --- diff --git a/Magick++/lib/Functions.cpp b/Magick++/lib/Functions.cpp index a9397ce4d..315321cd9 100644 --- a/Magick++/lib/Functions.cpp +++ b/Magick++/lib/Functions.cpp @@ -16,14 +16,6 @@ using namespace std; #include "Magick++/Functions.h" #include "Magick++/Exception.h" -#define GetPPException \ - ExceptionInfo \ - exceptionInfo; \ - GetExceptionInfo(&exceptionInfo) -#define ThrowPPException \ - throwException(exceptionInfo); \ - (void) DestroyExceptionInfo(&exceptionInfo) - static bool magick_initialized=false; // Clone C++ string as allocated C string, de-allocating any existing string diff --git a/Magick++/lib/Image.cpp b/Magick++/lib/Image.cpp index 7c460db2b..6897ab0ac 100644 --- a/Magick++/lib/Image.cpp +++ b/Magick++/lib/Image.cpp @@ -27,27 +27,6 @@ using namespace std; #define MagickPI 3.14159265358979323846264338327950288419716939937510 #define DegreesToRadians(x) (MagickPI*(x)/180.0) -#define GetPPException \ - ExceptionInfo \ - exceptionInfo; \ - GetExceptionInfo(&exceptionInfo) -#define ClonePPDrawException(wand) \ - ExceptionInfo \ - *exceptionInfo; \ - exceptionInfo=DrawCloneExceptionInfo(wand) -#define RestorePPChannelMask \ - SetPixelChannelMask(image(),channel_mask) -#define SetPPChannelMask(channel) \ - ChannelType \ - channel_mask; \ - channel_mask=SetImageChannelMask(image(),channel) -#define ThrowPPDrawException \ - throwException(*exceptionInfo); \ - (void) DestroyExceptionInfo(exceptionInfo) -#define ThrowPPException \ - throwException(exceptionInfo); \ - (void) DestroyExceptionInfo(&exceptionInfo) - MagickPPExport const char *Magick::borderGeometryDefault="6x6+0+0"; MagickPPExport const char *Magick::frameGeometryDefault="25x25+6+6"; MagickPPExport const char *Magick::raiseGeometryDefault="6x6+0+0"; @@ -3538,6 +3517,25 @@ void Magick::Image::opaque(const Color &opaqueColor_,const Color &penColor_) ThrowPPException; } +void Magick::Image::orderedDither(std::string thresholdMap_) +{ + modifyImage(); + GetPPException; + (void) OrderedPosterizeImage(image(),thresholdMap_.c_str(),&exceptionInfo); + ThrowPPException; +} + +void Magick::Image::orderedDitherChannel(const ChannelType channel_, + std::string thresholdMap_) +{ + modifyImage(); + GetPPException; + SetPPChannelMask(channel_); + (void) OrderedPosterizeImage(image(),thresholdMap_.c_str(),&exceptionInfo); + RestorePPChannelMask; + ThrowPPException; +} + void Magick::Image::perceptible(const double epsilon_) { modifyImage(); @@ -4038,19 +4036,6 @@ void Magick::Image::sample(const Geometry &geometry_) ThrowPPException; } -Magick::Quantum *Magick::Image::setPixels(const ssize_t x_,const ssize_t y_, - const size_t columns_,const size_t rows_) -{ - Quantum - *result; - - modifyImage(); - GetPPException; - result=(*QueueAuthenticPixels)(image(),x_,y_,columns_,rows_,&exceptionInfo); - ThrowPPException; - return(result); -} - void Magick::Image::scale(const Geometry &geometry_) { MagickCore::Image @@ -4085,6 +4070,72 @@ void Magick::Image::segment(const double clusterThreshold_, ThrowPPException; } +void Magick::Image::selectiveBlur(const double radius_,const double sigma_, + const double threshold_) +{ + MagickCore::Image + *newImage; + + GetPPException; + newImage=SelectiveBlurImage(constImage(),radius_,sigma_,threshold_, + &exceptionInfo); + replaceImage(newImage); + ThrowPPException; +} + +void Magick::Image::selectiveBlurChannel(const ChannelType channel_, + const double radius_,const double sigma_,const double threshold_) +{ + MagickCore::Image + *newImage; + + GetPPException; + SetPPChannelMask(channel_); + newImage=SelectiveBlurImage(constImage(),radius_,sigma_,threshold_, + &exceptionInfo); + RestorePPChannelMask; + replaceImage(newImage); + ThrowPPException; +} + +Magick::Image Magick::Image::separate(const ChannelType channel_) +{ + MagickCore::Image + *image; + + GetPPException; + image=SeparateImage(constImage(),channel_,&exceptionInfo); + ThrowPPException; + if (image == (MagickCore::Image *) NULL) + return(Magick::Image()); + else + return(Magick::Image(image)); +} + +void Magick::Image::sepiaTone(const double threshold_) +{ + MagickCore::Image + *newImage; + + GetPPException; + newImage=SepiaToneImage(constImage(),threshold_,&exceptionInfo); + replaceImage(newImage); + ThrowPPException; +} + +Magick::Quantum *Magick::Image::setPixels(const ssize_t x_,const ssize_t y_, + const size_t columns_,const size_t rows_) +{ + Quantum + *result; + + modifyImage(); + GetPPException; + result=(*QueueAuthenticPixels)(image(),x_,y_,columns_,rows_,&exceptionInfo); + ThrowPPException; + return(result); +} + void Magick::Image::shade(const double azimuth_,const double elevation_, const bool colorShading_) { @@ -4191,6 +4242,18 @@ std::string Magick::Image::signature(const bool force_) const return(std::string(property)); } +void Magick::Image::sketch(const double radius_,const double sigma_, + const double angle_) +{ + MagickCore::Image + *newImage; + + GetPPException; + newImage=SketchImage(constImage(),radius_,sigma_,angle_,&exceptionInfo); + replaceImage(newImage); + ThrowPPException; +} + void Magick::Image::solarize(const double factor_) { modifyImage(); @@ -4397,6 +4460,21 @@ void Magick::Image::thumbnail(const Geometry &geometry_) ThrowPPException; } +void Magick::Image::tint(const std::string opacity_) +{ + MagickCore::Image + *newImage; + + PixelInfo + color; + + GetPPException; + color=static_cast(constOptions()->fillColor()); + newImage=TintImage(constImage(),opacity_.c_str(),&color,&exceptionInfo); + replaceImage(newImage); + ThrowPPException; +} + void Magick::Image::transform(const Geometry &imageGeometry_) { modifyImage(); @@ -4516,6 +4594,20 @@ void Magick::Image::trim(void) ThrowPPException; } +Magick::Image Magick::Image::uniqueColors(void) +{ + MagickCore::Image + *image; + + GetPPException; + image=UniqueImageColors(constImage(),&exceptionInfo); + ThrowPPException; + if (image == (MagickCore::Image *) NULL) + return(Magick::Image()); + else + return(Magick::Image(image)); +} + void Magick::Image::unsharpmask(const double radius_,const double sigma_, const double amount_,const double threshold_) { @@ -4545,6 +4637,18 @@ void Magick::Image::unsharpmaskChannel(const ChannelType channel_, ThrowPPException; } +void Magick::Image::vignette(const double radius_,const double sigma_, + const ssize_t x_,const ssize_t y_) +{ + MagickCore::Image + *newImage; + + GetPPException; + newImage=VignetteImage(constImage(),radius_,sigma_,x_,y_,&exceptionInfo); + replaceImage(newImage); + ThrowPPException; +} + void Magick::Image::wave(const double amplitude_,const double wavelength_) { MagickCore::Image diff --git a/Magick++/lib/Magick++/Image.h b/Magick++/lib/Magick++/Image.h index 53f9f1187..de7c9ce16 100644 --- a/Magick++/lib/Magick++/Image.h +++ b/Magick++/lib/Magick++/Image.h @@ -1051,6 +1051,12 @@ namespace Magick // Change color of opaque pixel to specified pen color. void opaque(const Color &opaqueColor_,const Color &penColor_); + // Perform a ordered dither based on a number of pre-defined dithering + // threshold maps, but over multiple intensity levels. + void orderedDither(std::string thresholdMap_); + void orderedDitherChannel(const ChannelType channel_, + std::string thresholdMap_); + // Set each pixel whose value is less than epsilon to epsilon or // -epsilon (whichever is closer) otherwise the pixel value remains // unchanged. @@ -1189,12 +1195,6 @@ namespace Magick // Resize image by using pixel sampling algorithm void sample(const Geometry &geometry_); - // Allocates a pixel cache region to store image pixels as defined - // by the region rectangle. This area is subsequently transferred - // from the pixel cache to the image via syncPixels. - Quantum *setPixels(const ::ssize_t x_, const ::ssize_t y_, - const size_t columns_,const size_t rows_); - // Resize image by using simple ratio algorithm void scale(const Geometry &geometry_); @@ -1205,6 +1205,29 @@ namespace Magick void segment(const double clusterThreshold_=1.0, const double smoothingThreshold_=1.5); + // Selectively blur pixels within a contrast threshold. It is similar to + // the unsharpen mask that sharpens everything with contrast above a + // certain threshold. + void selectiveBlur(const double radius_,const double sigma_, + const double threshold_); + void selectiveBlurChannel(const ChannelType channel_,const double radius_, + const double sigma_,const double threshold_); + + // Separates a channel from the image and returns it as a grayscale image. + Image separate(const ChannelType channel_); + + // Applies a special effect to the image, similar to the effect achieved in + // a photo darkroom by sepia toning. Threshold ranges from 0 to + // QuantumRange and is a measure of the extent of the sepia toning. + // A threshold of 80% is a good starting point for a reasonable tone. + void sepiaTone(const double threshold_); + + // Allocates a pixel cache region to store image pixels as defined + // by the region rectangle. This area is subsequently transferred + // from the pixel cache to the image via syncPixels. + Quantum *setPixels(const ::ssize_t x_, const ::ssize_t y_, + const size_t columns_,const size_t rows_); + // Shade image using distant light source void shade(const double azimuth_=30,const double elevation_=30, const bool colorShading_=false); @@ -1236,6 +1259,13 @@ namespace Magick // modified. std::string signature(const bool force_=false) const; + // Simulates a pencil sketch. We convolve the image with a Gaussian + // operator of the given radius and standard deviation (sigma). For + // reasonable results, radius should be larger than sigma. Use a + // radius of 0 and SketchImage() selects a suitable radius for you. + void sketch(const double radius_=0.0,const double sigma_=1.0, + const double angle_=0.0); + // Solarize image (similar to effect seen when exposing a // photographic film to light during the development process) void solarize(const double factor_=50.0); @@ -1288,6 +1318,11 @@ namespace Magick // Resize image to thumbnail size void thumbnail(const Geometry &geometry_); + // Applies a color vector to each pixel in the image. The length of the + // vector is 0 for black and white and at its maximum for the midtones. + // The vector weighting function is f(x)=(1-(4.0*((x-0.5)*(x-0.5)))) + void tint(const std::string opacity_); + // Transform image based on image and crop geometries // Crop geometry is optional void transform(const Geometry &imageGeometry_); @@ -1322,6 +1357,9 @@ namespace Magick // Trim edges that are the background color from the image void trim(void); + // Returns the unique colors of an image. + Image uniqueColors(void); + // Replace image with a sharpened version of the original image // using the unsharp mask algorithm. // radius_ @@ -1339,6 +1377,10 @@ namespace Magick void unsharpmaskChannel(const ChannelType channel_,const double radius_, const double sigma_,const double amount_,const double threshold_); + // Softens the edges of the image in vignette style. + void vignette(const double radius_=0.0,const double sigma_=1.0, + const ssize_t x_=0,const ssize_t y_=0); + // Map image pixels to a sine wave void wave(const double amplitude_=25.0,const double wavelength_=150.0); diff --git a/Magick++/lib/Magick++/Include.h b/Magick++/lib/Magick++/Include.h index 0c9e840a7..9fd087ac4 100644 --- a/Magick++/lib/Magick++/Include.h +++ b/Magick++/lib/Magick++/Include.h @@ -1303,6 +1303,7 @@ namespace Magick using MagickCore::NoValue; using MagickCore::OilPaintImage; using MagickCore::OpaquePaintImage; + using MagickCore::OrderedPosterizeImage; using MagickCore::OptionError; using MagickCore::OptionFatalError; using MagickCore::OptionWarning; @@ -1348,7 +1349,9 @@ namespace Magick using MagickCore::SampleImage; using MagickCore::ScaleImage; using MagickCore::SegmentImage; + using MagickCore::SelectiveBlurImage; using MagickCore::SeparateImage; + using MagickCore::SepiaToneImage; using MagickCore::SetClientName; using MagickCore::SetGeometry; using MagickCore::SetImageAlpha; @@ -1381,6 +1384,8 @@ namespace Magick using MagickCore::SigmoidalContrastImage; using MagickCore::SignatureImage; using MagickCore::SimilarityImage; + using MagickCore::SketchImage; + using MagickCore::SmushImages; using MagickCore::SolarizeImage; using MagickCore::SparseColorImage; using MagickCore::SpliceImage; @@ -1399,6 +1404,7 @@ namespace Magick using MagickCore::SyncAuthenticPixels; using MagickCore::TextureImage; using MagickCore::ThrowException; + using MagickCore::TintImage; using MagickCore::TransformImage; using MagickCore::TransformImageColorspace; using MagickCore::TransparentPaintImage; @@ -1411,8 +1417,10 @@ namespace Magick using MagickCore::TypeWarning; using MagickCore::UndefinedException; using MagickCore::UndefinedRegistryType; + using MagickCore::UniqueImageColors; using MagickCore::UnregisterMagickInfo; using MagickCore::UnsharpMaskImage; + using MagickCore::VignetteImage; using MagickCore::CacheView; using MagickCore::WaveImage; using MagickCore::WhiteThresholdImage; @@ -1430,4 +1438,30 @@ namespace Magick } +////////////////////////////////////////////////////////////////////// +// +// No user-serviceable parts beyond this point +// +////////////////////////////////////////////////////////////////////// +#define GetPPException \ + MagickCore::ExceptionInfo \ + exceptionInfo; \ + MagickCore::GetExceptionInfo(&exceptionInfo) +#define ClonePPDrawException(wand) \ + MagickCore::ExceptionInfo \ + *exceptionInfo; \ + exceptionInfo=MagickCore::DrawCloneExceptionInfo(wand) +#define RestorePPChannelMask \ + MagickCore::SetPixelChannelMask(image(),channel_mask) +#define SetPPChannelMask(channel) \ + MagickCore::ChannelType \ + channel_mask; \ + channel_mask=MagickCore::SetImageChannelMask(image(),channel) +#define ThrowPPDrawException \ + throwException(*exceptionInfo); \ + (void) MagickCore::DestroyExceptionInfo(exceptionInfo) +#define ThrowPPException \ + throwException(exceptionInfo); \ + (void) MagickCore::DestroyExceptionInfo(&exceptionInfo) + #endif // Magick_Include_header diff --git a/Magick++/lib/Magick++/STL.h b/Magick++/lib/Magick++/STL.h index 2dea2ce03..bfe53c762 100644 --- a/Magick++/lib/Magick++/STL.h +++ b/Magick++/lib/Magick++/STL.h @@ -2617,6 +2617,24 @@ namespace Magick (void) MagickCore::DestroyExceptionInfo( &exceptionInfo ); } + // 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; + + GetPPException; + linkImages(first_,last_); + newImage=MagickCore::SmushImages(first_->constImage(), + (MagickBooleanType) stack_,offset_,&exceptionInfo); + unlinkImages(first_,last_); + smushedImage_->replaceImage(newImage); + ThrowPPException; + } + // Write Images template void writeImages( InputIterator first_, diff --git a/Magick++/lib/Options.cpp b/Magick++/lib/Options.cpp index a1328d631..4c262c11c 100644 --- a/Magick++/lib/Options.cpp +++ b/Magick++/lib/Options.cpp @@ -22,13 +22,6 @@ #define MagickPI 3.14159265358979323846264338327950288419716939937510 #define DegreesToRadians(x) (MagickPI*(x)/180.0) -#define GetPPException \ - ExceptionInfo \ - exceptionInfo; \ - GetExceptionInfo(&exceptionInfo) -#define ThrowPPException \ - throwException(exceptionInfo); \ - (void) DestroyExceptionInfo(&exceptionInfo) Magick::Options::Options(void) : _imageInfo(static_cast(AcquireMagickMemory(