Add greyscale option to threshold operation (#480)

This commit is contained in:
Matt Hirsch 2016-07-03 14:32:07 -04:00 committed by Lovell Fuller
parent 4b98dbb454
commit 85f20c6e1b
8 changed files with 55 additions and 3 deletions

View File

@ -391,12 +391,14 @@ When a `sigma` is provided, performs a slower, more accurate sharpen of the L ch
* `flat`, if present, is a Number representing the level of sharpening to apply to "flat" areas, defaulting to a value of 1.0.
* `jagged`, if present, is a Number representing the level of sharpening to apply to "jagged" areas, defaulting to a value of 2.0.
#### threshold([threshold])
#### threshold([threshold], [options])
Converts all pixels in the image to greyscale white or black. Any pixel greather-than-or-equal-to the threshold (0..255) will be white. All others will be black.
* `threshold`, if present, is a Number, representing the level above which pixels will be forced to white.
* `options`, an options object that may contain a boolean `grayscale` or `greyscale`. When `grayscale` is `true`, `threshold` returns a black and white image, and when `false` a color image with each channel thresholded independently. The default is `grayscale: true` when omitted.
#### gamma([gamma])
Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma` then increasing the encoding (brighten) post-resize at a factor of `gamma`.

View File

@ -85,6 +85,7 @@ var Sharp = function(input, options) {
sharpenFlat: 1,
sharpenJagged: 2,
threshold: 0,
thresholdGrayscale: true,
gamma: 0,
greyscale: false,
normalize: 0,
@ -487,7 +488,7 @@ Sharp.prototype.sharpen = function(sigma, flat, jagged) {
return this;
};
Sharp.prototype.threshold = function(threshold) {
Sharp.prototype.threshold = function(threshold, options) {
if (typeof threshold === 'undefined') {
this.options.threshold = 128;
} else if (typeof threshold === 'boolean') {
@ -497,6 +498,14 @@ Sharp.prototype.threshold = function(threshold) {
} else {
throw new Error('Invalid threshold (0 to 255) ' + threshold);
}
if(typeof options === 'undefined' ||
options.greyscale === true || options.grayscale === true) {
this.options.thresholdGrayscale = true;
} else {
this.options.thresholdGrayscale = false;
}
return this;
};

View File

@ -327,4 +327,11 @@ namespace sharp {
);
}
VImage Threshold(VImage image, double const threshold, bool const thresholdGrayscale) {
if(!thresholdGrayscale) {
return image >= threshold;
}
return image.colourspace(VIPS_INTERPRETATION_B_W) >= threshold;
}
} // namespace sharp

View File

@ -54,6 +54,11 @@ namespace sharp {
*/
VImage TileCache(VImage image, double const factor);
/*
Threshold an image
*/
VImage Threshold(VImage image, double const threshold, bool const thresholdColor);
} // namespace sharp
#endif // SRC_OPERATIONS_H_

View File

@ -52,6 +52,7 @@ using sharp::Blur;
using sharp::Sharpen;
using sharp::EntropyCrop;
using sharp::TileCache;
using sharp::Threshold;
using sharp::ImageType;
using sharp::ImageTypeId;
@ -625,7 +626,7 @@ class PipelineWorker : public AsyncWorker {
// Threshold - must happen before blurring, due to the utility of blurring after thresholding
if (shouldThreshold) {
image = image.colourspace(VIPS_INTERPRETATION_B_W) >= baton->threshold;
image = Threshold(image, baton->threshold, baton->thresholdGrayscale);
}
// Blur
@ -1107,6 +1108,7 @@ NAN_METHOD(pipeline) {
baton->sharpenFlat = attrAs<double>(options, "sharpenFlat");
baton->sharpenJagged = attrAs<double>(options, "sharpenJagged");
baton->threshold = attrAs<int32_t>(options, "threshold");
baton->thresholdGrayscale = attrAs<bool>(options, "thresholdGrayscale");
baton->gamma = attrAs<double>(options, "gamma");
baton->greyscale = attrAs<bool>(options, "greyscale");
baton->normalize = attrAs<bool>(options, "normalize");

View File

@ -58,6 +58,7 @@ struct PipelineBaton {
double sharpenFlat;
double sharpenJagged;
int threshold;
bool thresholdGrayscale;
double gamma;
bool greyscale;
bool normalize;
@ -113,6 +114,7 @@ struct PipelineBaton {
sharpenFlat(1.0),
sharpenJagged(2.0),
threshold(0),
thresholdGrayscale(true),
gamma(0.0),
greyscale(false),
normalize(false),

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -54,6 +54,19 @@ describe('Threshold', function() {
});
});
it('threshold grayscale: true (=128)', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.threshold(128,{'grayscale':true})
.toBuffer(function(err, data, info) {
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fixtures.assertSimilar(fixtures.expected('threshold-128.jpg'), data, done);
});
});
it('threshold default jpeg', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
@ -101,6 +114,18 @@ describe('Threshold', function() {
});
}
it('color threshold', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.threshold(128,{'grayscale':false})
.toBuffer(function(err, data, info) {
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fixtures.assertSimilar(fixtures.expected('threshold-color-128.jpg'), data, done);
});
});
it('invalid threshold -1', function() {
assert.throws(function() {
sharp(fixtures.inputJpg).threshold(-1);