Add bandbool feature for channel-wise boolean operations (#496)

This commit is contained in:
Matt Hirsch
2016-07-07 16:03:49 -04:00
committed by Lovell Fuller
parent a982cfdb20
commit 65b7f7d7d5
12 changed files with 124 additions and 0 deletions

View File

@@ -392,4 +392,11 @@ namespace sharp {
return image.colourspace(VIPS_INTERPRETATION_B_W) >= threshold;
}
/*
Perform boolean/bitwise operation on image color channels - results in one channel image
*/
VImage Bandbool(VImage image, VipsOperationBoolean const boolean) {
return image.bandbool(boolean);
}
} // namespace sharp

View File

@@ -82,6 +82,11 @@ namespace sharp {
*/
VImage Threshold(VImage image, double const threshold, bool const thresholdColor);
/*
Perform boolean/bitwise operation on image color channels - results in one channel image
*/
VImage Bandbool(VImage image, VipsOperationBoolean const boolean);
} // namespace sharp
#endif // SRC_OPERATIONS_H_

View File

@@ -55,6 +55,7 @@ using sharp::Sharpen;
using sharp::EntropyCrop;
using sharp::TileCache;
using sharp::Threshold;
using sharp::Bandbool;
using sharp::ImageType;
using sharp::ImageTypeId;
@@ -470,6 +471,8 @@ class PipelineWorker : public AsyncWorker {
bool shouldSharpen = baton->sharpenSigma != 0.0;
bool shouldThreshold = baton->threshold != 0;
bool shouldCutout = baton->overlayCutout;
bool shouldBandbool = baton->bandBoolOp < VIPS_OPERATION_BOOLEAN_LAST &&
baton->bandBoolOp >= VIPS_OPERATION_BOOLEAN_AND;
bool shouldPremultiplyAlpha = HasAlpha(image) &&
(shouldAffineTransform || shouldBlur || shouldConv || shouldSharpen || (hasOverlay && !shouldCutout));
@@ -774,6 +777,11 @@ class PipelineWorker : public AsyncWorker {
}
}
// Apply per-channel Bandbool bitwise operations after all other operations
if (shouldBandbool) {
image = Bandbool(image, baton->bandBoolOp);
}
// Override EXIF Orientation tag
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
SetExifOrientation(image, baton->withMetadataOrientation);
@@ -1194,6 +1202,15 @@ NAN_METHOD(pipeline) {
baton->convKernel[i] = To<double>(Get(kdata, i).ToLocalChecked()).FromJust();
}
}
// Bandbool operation
std::string opStr = attrAsStr(options, "bandBoolOp");
if(opStr == "and" ) {
baton->bandBoolOp = VIPS_OPERATION_BOOLEAN_AND;
} else if(opStr == "or") {
baton->bandBoolOp = VIPS_OPERATION_BOOLEAN_OR;
} else if(opStr == "eor") {
baton->bandBoolOp = VIPS_OPERATION_BOOLEAN_EOR;
}
// Function to notify of queue length changes
Callback *queueListener = new Callback(

View File

@@ -92,6 +92,7 @@ struct PipelineBaton {
int convKernelHeight;
double convKernelScale;
double convKernelOffset;
VipsOperationBoolean bandBoolOp;
int tileSize;
int tileOverlap;
VipsForeignDzContainer tileContainer;
@@ -151,6 +152,7 @@ struct PipelineBaton {
convKernelHeight(0),
convKernelScale(0.0),
convKernelOffset(0.0),
bandBoolOp(VIPS_OPERATION_BOOLEAN_LAST),
tileSize(256),
tileOverlap(0),
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),