Framework to support -color-threshold option

This commit is contained in:
Cristy
2020-02-22 08:17:19 -05:00
parent 68eee2568f
commit ca5ba780a7
9 changed files with 109 additions and 59 deletions
+6 -4
View File
@@ -1528,14 +1528,16 @@ MagickExport MagickStatusType ParseMetaGeometry(const char *geometry,ssize_t *x,
(void) ParseGeometry(geometry,&geometry_info);
area=geometry_info.rho+sqrt(MagickEpsilon);
distance=sqrt((double) former_width*former_height);
scale.x=(double) former_width*PerceptibleReciprocal(distance/sqrt(area));
scale.y=(double) former_height*PerceptibleReciprocal(distance/sqrt(area));
scale.x=(double) former_width*PerceptibleReciprocal(distance*
PerceptibleReciprocal(sqrt(area)));
scale.y=(double) former_height*PerceptibleReciprocal(distance*
PerceptibleReciprocal(sqrt(area)));
if ((scale.x < (double) *width) || (scale.y < (double) *height))
{
*width=(unsigned long) (former_width*PerceptibleReciprocal(
distance/sqrt(area)));
distance*PerceptibleReciprocal(sqrt(area))));
*height=(unsigned long) (former_height*PerceptibleReciprocal(
distance/sqrt(area)));
distance*PerceptibleReciprocal(sqrt(area))));
}
former_width=(*width);
former_height=(*height);
+8 -38
View File
@@ -1200,28 +1200,29 @@ MagickExport MagickBooleanType ClampImage(Image *image,ExceptionInfo *exception)
% The format of the ColorThresholdImage method is:
%
% MagickBooleanType ColorThresholdImage(Image *image,
% const char *threshold,ExceptionInfo *exception)
% const PixelInfo *start_color,const PixelInfo *stop_color,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o threshold: define the threshold value.
% o start_color: start color of the thresholding.
%
% o stop_color: stop color of the thresholding.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType ColorThresholdImage(Image *image,
const char *thresholds,ExceptionInfo *exception)
const PixelInfo *start_color,const PixelInfo *stop_color,
ExceptionInfo *exception)
{
#define ThresholdImageTag "Threshold/Image"
CacheView
*image_view;
GeometryInfo
geometry_info;
MagickBooleanType
status;
@@ -1231,9 +1232,6 @@ MagickExport MagickBooleanType ColorThresholdImage(Image *image,
PixelInfo
threshold;
MagickStatusType
flags;
ssize_t
y;
@@ -1241,40 +1239,12 @@ MagickExport MagickBooleanType ColorThresholdImage(Image *image,
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (thresholds == (const char *) NULL)
return(MagickTrue);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
(void) SetImageColorspace(image,sRGBColorspace,exception);
GetPixelInfo(image,&threshold);
flags=ParseGeometry(thresholds,&geometry_info);
threshold.red=geometry_info.rho;
threshold.green=geometry_info.rho;
threshold.blue=geometry_info.rho;
threshold.black=geometry_info.rho;
threshold.alpha=100.0;
if ((flags & SigmaValue) != 0)
threshold.green=geometry_info.sigma;
if ((flags & XiValue) != 0)
threshold.blue=geometry_info.xi;
if ((flags & PsiValue) != 0)
threshold.alpha=geometry_info.psi;
if (threshold.colorspace == CMYKColorspace)
{
if ((flags & PsiValue) != 0)
threshold.black=geometry_info.psi;
if ((flags & ChiValue) != 0)
threshold.alpha=geometry_info.chi;
}
if ((flags & PercentValue) != 0)
{
threshold.red*=(MagickRealType) (QuantumRange/100.0);
threshold.green*=(MagickRealType) (QuantumRange/100.0);
threshold.blue*=(MagickRealType) (QuantumRange/100.0);
threshold.black*=(MagickRealType) (QuantumRange/100.0);
threshold.alpha*=(MagickRealType) (QuantumRange/100.0);
}
threshold=(*start_color);
/*
White threshold image.
*/
+2 -1
View File
@@ -46,7 +46,8 @@ extern MagickExport MagickBooleanType
BilevelImage(Image *,const double,ExceptionInfo *),
BlackThresholdImage(Image *,const char *,ExceptionInfo *),
ClampImage(Image *,ExceptionInfo *),
ColorThresholdImage(Image *,const char *,ExceptionInfo *),
ColorThresholdImage(Image *,const PixelInfo *,const PixelInfo *,
ExceptionInfo *),
ListThresholdMaps(FILE *,ExceptionInfo *),
OrderedDitherImage(Image *,const char *,ExceptionInfo *),
PerceptibleImage(Image *,const double,ExceptionInfo *),
+46
View File
@@ -1785,6 +1785,52 @@ WandExport MagickBooleanType MagickColorMatrixImage(MagickWand *wand,
% %
% %
% %
% M a g i c k C o l o r T h r e s h o l d I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MagickColorThresholdImage() forces all pixels in the color range to white
% otherwise black.
%
% The format of the MagickWhiteThresholdImage method is:
%
% MagickBooleanType MagickWhiteThresholdImage(MagickWand *wand,
% const PixelWand *start_color,const PixelWand *stop_color)
%
% A description of each parameter follows:
%
% o wand: the magick wand.
%
% o start-color: the start color pixel wand.
%
% o stop-color: the stop color pixel wand.
%
*/
WandExport MagickBooleanType MagickColorThresholdImage(MagickWand *wand,
const PixelWand *start_color,const PixelWand *stop_color)
{
PixelInfo
start,
stop;
assert(wand != (MagickWand *) NULL);
assert(wand->signature == MagickWandSignature);
if (wand->debug != MagickFalse)
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
if (wand->images == (Image *) NULL)
ThrowWandException(WandError,"ContainsNoImages",wand->name);
PixelGetMagickColor(start_color,&start);
PixelGetMagickColor(stop_color,&stop);
return(ColorThresholdImage(wand->images,&start,&stop,wand->exception));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a g i c k C o m b i n e I m a g e s %
% %
% %
+1
View File
@@ -113,6 +113,7 @@ extern WandExport MagickBooleanType
MagickColorDecisionListImage(MagickWand *,const char *),
MagickColorizeImage(MagickWand *,const PixelWand *,const PixelWand *),
MagickColorMatrixImage(MagickWand *,const KernelInfo *),
MagickColorThresholdImage(MagickWand *,const PixelWand *,const PixelWand *),
MagickCommentImage(MagickWand *,const char *),
MagickCompositeImage(MagickWand *,const MagickWand *,const CompositeOperator,
const MagickBooleanType,const ssize_t,const ssize_t),
+6 -1
View File
@@ -1195,11 +1195,16 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
}
if (LocaleCompare("color-threshold",option+1) == 0)
{
PixelInfo
start_color,
stop_color;
/*
Color threshold image.
*/
(void) SyncImageSettings(mogrify_info,*image,exception);
(void) ColorThresholdImage(*image,argv[i+1],exception);
(void) ColorThresholdImage(*image,&start_color,&stop_color,
exception);
break;
}
if (LocaleCompare("compose",option+1) == 0)
+6 -1
View File
@@ -2067,9 +2067,14 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
}
if (LocaleCompare("color-threshold",option+1) == 0)
{
PixelInfo
start_color,
stop_color;
if (IsGeometry(arg1) == MagickFalse)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
(void) ColorThresholdImage(_image,arg1,_exception);
(void) ColorThresholdImage(_image,&start_color,&stop_color,
_exception);
break;
}
if (LocaleCompare("connected-components",option+1) == 0)
+16 -6
View File
@@ -577,8 +577,8 @@ static struct
{"clip-limit", RealReference} } },
{ "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
{"iterations", IntegerReference}, {"tolerance", RealReference} } },
{ "ColorThreshold", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "ColorThreshold", { {"start-color", StringReference},
{"stop-color", StringReference}, {"channel", MagickChannelOptions} } },
};
static SplayTreeInfo
@@ -11543,10 +11543,20 @@ Mogrify(ref,...)
}
case 151: /* ColorThreshold */
{
if (attribute_flag[0] == 0)
argument_list[0].string_reference="50%";
if (attribute_flag[2] != 0)
channel=(ChannelType) argument_list[2].integer_reference;
PixelInfo
start_color,
stop_color;
(void) QueryColorCompliance("black",AllCompliance,&start_color,
exception);
(void) QueryColorCompliance("white",AllCompliance,&stop_color,
exception);
if (attribute_flag[0] != 0)
(void) QueryColorCompliance(argument_list[0].string_reference,
AllCompliance,&start_color,exception);
if (attribute_flag[1] != 0)
(void) QueryColorCompliance(argument_list[1].string_reference,
AllCompliance,&stop_color,exception);
channel_mask=SetImageChannelMask(image,channel);
(void) ColorThresholdImage(image,argument_list[0].string_reference,
exception);
+18 -8
View File
@@ -577,8 +577,8 @@ static struct
{"clip-limit", RealReference} } },
{ "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
{"iterations", IntegerReference}, {"tolerance", RealReference} } },
{ "ColorThreshold", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "ColorThreshold", { {"start-color", StringReference},
{"stop-color", StringReference}, {"channel", MagickChannelOptions} } },
};
static SplayTreeInfo
@@ -11547,14 +11547,24 @@ Mogrify(ref,...)
geometry_info.xi,exception);
break;
}
case 151: /* WhiteThreshold */
case 151: /* ColorThreshold */
{
if (attribute_flag[0] == 0)
argument_list[0].string_reference="50%";
if (attribute_flag[2] != 0)
channel=(ChannelType) argument_list[2].integer_reference;
PixelInfo
start_color,
stop_color;
(void) QueryColorCompliance("black",AllCompliance,&start_color,
exception);
(void) QueryColorCompliance("white",AllCompliance,&stop_color,
exception);
if (attribute_flag[0] != 0)
(void) QueryColorCompliance(argument_list[0].string_reference,
AllCompliance,&start_color,exception);
if (attribute_flag[1] != 0)
(void) QueryColorCompliance(argument_list[1].string_reference,
AllCompliance,&stop_color,exception);
channel_mask=SetImageChannelMask(image,channel);
(void) WhiteThresholdImage(image,argument_list[0].string_reference,
(void) ColorThresholdImage(image,argument_list[0].string_reference,
exception);
(void) SetImageChannelMask(image,channel_mask);
break;