mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Add greyscale option to threshold operation (#480)
This commit is contained in:
parent
4b98dbb454
commit
85f20c6e1b
@ -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.
|
* `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.
|
* `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.
|
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.
|
* `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])
|
#### 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`.
|
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`.
|
||||||
|
11
index.js
11
index.js
@ -85,6 +85,7 @@ var Sharp = function(input, options) {
|
|||||||
sharpenFlat: 1,
|
sharpenFlat: 1,
|
||||||
sharpenJagged: 2,
|
sharpenJagged: 2,
|
||||||
threshold: 0,
|
threshold: 0,
|
||||||
|
thresholdGrayscale: true,
|
||||||
gamma: 0,
|
gamma: 0,
|
||||||
greyscale: false,
|
greyscale: false,
|
||||||
normalize: 0,
|
normalize: 0,
|
||||||
@ -487,7 +488,7 @@ Sharp.prototype.sharpen = function(sigma, flat, jagged) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sharp.prototype.threshold = function(threshold) {
|
Sharp.prototype.threshold = function(threshold, options) {
|
||||||
if (typeof threshold === 'undefined') {
|
if (typeof threshold === 'undefined') {
|
||||||
this.options.threshold = 128;
|
this.options.threshold = 128;
|
||||||
} else if (typeof threshold === 'boolean') {
|
} else if (typeof threshold === 'boolean') {
|
||||||
@ -497,6 +498,14 @@ Sharp.prototype.threshold = function(threshold) {
|
|||||||
} else {
|
} else {
|
||||||
throw new Error('Invalid threshold (0 to 255) ' + threshold);
|
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;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
} // namespace sharp
|
||||||
|
@ -54,6 +54,11 @@ namespace sharp {
|
|||||||
*/
|
*/
|
||||||
VImage TileCache(VImage image, double const factor);
|
VImage TileCache(VImage image, double const factor);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Threshold an image
|
||||||
|
*/
|
||||||
|
VImage Threshold(VImage image, double const threshold, bool const thresholdColor);
|
||||||
|
|
||||||
} // namespace sharp
|
} // namespace sharp
|
||||||
|
|
||||||
#endif // SRC_OPERATIONS_H_
|
#endif // SRC_OPERATIONS_H_
|
||||||
|
@ -52,6 +52,7 @@ using sharp::Blur;
|
|||||||
using sharp::Sharpen;
|
using sharp::Sharpen;
|
||||||
using sharp::EntropyCrop;
|
using sharp::EntropyCrop;
|
||||||
using sharp::TileCache;
|
using sharp::TileCache;
|
||||||
|
using sharp::Threshold;
|
||||||
|
|
||||||
using sharp::ImageType;
|
using sharp::ImageType;
|
||||||
using sharp::ImageTypeId;
|
using sharp::ImageTypeId;
|
||||||
@ -625,7 +626,7 @@ class PipelineWorker : public AsyncWorker {
|
|||||||
|
|
||||||
// Threshold - must happen before blurring, due to the utility of blurring after thresholding
|
// Threshold - must happen before blurring, due to the utility of blurring after thresholding
|
||||||
if (shouldThreshold) {
|
if (shouldThreshold) {
|
||||||
image = image.colourspace(VIPS_INTERPRETATION_B_W) >= baton->threshold;
|
image = Threshold(image, baton->threshold, baton->thresholdGrayscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur
|
// Blur
|
||||||
@ -1107,6 +1108,7 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->sharpenFlat = attrAs<double>(options, "sharpenFlat");
|
baton->sharpenFlat = attrAs<double>(options, "sharpenFlat");
|
||||||
baton->sharpenJagged = attrAs<double>(options, "sharpenJagged");
|
baton->sharpenJagged = attrAs<double>(options, "sharpenJagged");
|
||||||
baton->threshold = attrAs<int32_t>(options, "threshold");
|
baton->threshold = attrAs<int32_t>(options, "threshold");
|
||||||
|
baton->thresholdGrayscale = attrAs<bool>(options, "thresholdGrayscale");
|
||||||
baton->gamma = attrAs<double>(options, "gamma");
|
baton->gamma = attrAs<double>(options, "gamma");
|
||||||
baton->greyscale = attrAs<bool>(options, "greyscale");
|
baton->greyscale = attrAs<bool>(options, "greyscale");
|
||||||
baton->normalize = attrAs<bool>(options, "normalize");
|
baton->normalize = attrAs<bool>(options, "normalize");
|
||||||
|
@ -58,6 +58,7 @@ struct PipelineBaton {
|
|||||||
double sharpenFlat;
|
double sharpenFlat;
|
||||||
double sharpenJagged;
|
double sharpenJagged;
|
||||||
int threshold;
|
int threshold;
|
||||||
|
bool thresholdGrayscale;
|
||||||
double gamma;
|
double gamma;
|
||||||
bool greyscale;
|
bool greyscale;
|
||||||
bool normalize;
|
bool normalize;
|
||||||
@ -113,6 +114,7 @@ struct PipelineBaton {
|
|||||||
sharpenFlat(1.0),
|
sharpenFlat(1.0),
|
||||||
sharpenJagged(2.0),
|
sharpenJagged(2.0),
|
||||||
threshold(0),
|
threshold(0),
|
||||||
|
thresholdGrayscale(true),
|
||||||
gamma(0.0),
|
gamma(0.0),
|
||||||
greyscale(false),
|
greyscale(false),
|
||||||
normalize(false),
|
normalize(false),
|
||||||
|
BIN
test/fixtures/expected/threshold-color-128.jpg
vendored
Normal file
BIN
test/fixtures/expected/threshold-color-128.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@ -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) {
|
it('threshold default jpeg', function(done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240)
|
.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() {
|
it('invalid threshold -1', function() {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
sharp(fixtures.inputJpg).threshold(-1);
|
sharp(fixtures.inputJpg).threshold(-1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user