mirror of
https://github.com/ImageMagick/ImageMagick.git
synced 2026-06-12 15:37:14 +02:00
Framework to support -color-threshold option
This commit is contained in:
@@ -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
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 *),
|
||||
|
||||
@@ -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 %
|
||||
% %
|
||||
% %
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user