mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Expose WebP smartDeblock output option
This commit is contained in:
parent
3154af776e
commit
8afec170ed
@ -439,6 +439,7 @@ Use these WebP options for output image.
|
||||
| [options.lossless] | <code>boolean</code> | <code>false</code> | use lossless compression mode |
|
||||
| [options.nearLossless] | <code>boolean</code> | <code>false</code> | use near_lossless compression mode |
|
||||
| [options.smartSubsample] | <code>boolean</code> | <code>false</code> | use high quality chroma subsampling |
|
||||
| [options.smartDeblock] | <code>boolean</code> | <code>false</code> | auto-adjust the deblocking filter, can improve low contrast edges (slow) |
|
||||
| [options.preset] | <code>string</code> | <code>"'default'"</code> | named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text |
|
||||
| [options.effort] | <code>number</code> | <code>4</code> | CPU effort, between 0 (fastest) and 6 (slowest) |
|
||||
| [options.loop] | <code>number</code> | <code>0</code> | number of animation iterations, use 0 for infinite animation |
|
||||
|
@ -8,6 +8,8 @@ Requires libvips v8.16.0-rc2
|
||||
|
||||
* Add `isPalette` and `bitsPerSample` to metadata, deprecate `paletteBitDepth`.
|
||||
|
||||
* Expose WebP `smartDeblock` output option.
|
||||
|
||||
* TypeScript: Ensure channel counts use the correct range.
|
||||
[#4197](https://github.com/lovell/sharp/pull/4197)
|
||||
[@DavidVaness](https://github.com/DavidVaness)
|
||||
|
File diff suppressed because one or more lines are too long
@ -300,6 +300,7 @@ const Sharp = function (input, options) {
|
||||
webpLossless: false,
|
||||
webpNearLossless: false,
|
||||
webpSmartSubsample: false,
|
||||
webpSmartDeblock: false,
|
||||
webpPreset: 'default',
|
||||
webpEffort: 4,
|
||||
webpMinSize: false,
|
||||
|
@ -623,6 +623,7 @@ function png (options) {
|
||||
* @param {boolean} [options.lossless=false] - use lossless compression mode
|
||||
* @param {boolean} [options.nearLossless=false] - use near_lossless compression mode
|
||||
* @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling
|
||||
* @param {boolean} [options.smartDeblock=false] - auto-adjust the deblocking filter, can improve low contrast edges (slow)
|
||||
* @param {string} [options.preset='default'] - named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text
|
||||
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest)
|
||||
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
||||
@ -658,6 +659,9 @@ function webp (options) {
|
||||
if (is.defined(options.smartSubsample)) {
|
||||
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
|
||||
}
|
||||
if (is.defined(options.smartDeblock)) {
|
||||
this._setBooleanOption('webpSmartDeblock', options.smartDeblock);
|
||||
}
|
||||
if (is.defined(options.preset)) {
|
||||
if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) {
|
||||
this.options.webpPreset = options.preset;
|
||||
|
@ -929,6 +929,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
->set("lossless", baton->webpLossless)
|
||||
->set("near_lossless", baton->webpNearLossless)
|
||||
->set("smart_subsample", baton->webpSmartSubsample)
|
||||
->set("smart_deblock", baton->webpSmartDeblock)
|
||||
->set("preset", baton->webpPreset)
|
||||
->set("effort", baton->webpEffort)
|
||||
->set("min_size", baton->webpMinSize)
|
||||
@ -1136,6 +1137,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
->set("lossless", baton->webpLossless)
|
||||
->set("near_lossless", baton->webpNearLossless)
|
||||
->set("smart_subsample", baton->webpSmartSubsample)
|
||||
->set("smart_deblock", baton->webpSmartDeblock)
|
||||
->set("preset", baton->webpPreset)
|
||||
->set("effort", baton->webpEffort)
|
||||
->set("min_size", baton->webpMinSize)
|
||||
@ -1419,6 +1421,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
{"lossless", baton->webpLossless ? "true" : "false"},
|
||||
{"near_lossless", baton->webpNearLossless ? "true" : "false"},
|
||||
{"smart_subsample", baton->webpSmartSubsample ? "true" : "false"},
|
||||
{"smart_deblock", baton->webpSmartDeblock ? "true" : "false"},
|
||||
{"preset", vips_enum_nick(VIPS_TYPE_FOREIGN_WEBP_PRESET, baton->webpPreset)},
|
||||
{"min_size", baton->webpMinSize ? "true" : "false"},
|
||||
{"mixed", baton->webpMixed ? "true" : "false"},
|
||||
@ -1676,6 +1679,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->webpLossless = sharp::AttrAsBool(options, "webpLossless");
|
||||
baton->webpNearLossless = sharp::AttrAsBool(options, "webpNearLossless");
|
||||
baton->webpSmartSubsample = sharp::AttrAsBool(options, "webpSmartSubsample");
|
||||
baton->webpSmartDeblock = sharp::AttrAsBool(options, "webpSmartDeblock");
|
||||
baton->webpPreset = sharp::AttrAsEnum<VipsForeignWebpPreset>(options, "webpPreset", VIPS_TYPE_FOREIGN_WEBP_PRESET);
|
||||
baton->webpEffort = sharp::AttrAsUint32(options, "webpEffort");
|
||||
baton->webpMinSize = sharp::AttrAsBool(options, "webpMinSize");
|
||||
|
@ -157,6 +157,7 @@ struct PipelineBaton {
|
||||
bool webpNearLossless;
|
||||
bool webpLossless;
|
||||
bool webpSmartSubsample;
|
||||
bool webpSmartDeblock;
|
||||
VipsForeignWebpPreset webpPreset;
|
||||
int webpEffort;
|
||||
bool webpMinSize;
|
||||
@ -328,6 +329,7 @@ struct PipelineBaton {
|
||||
webpNearLossless(false),
|
||||
webpLossless(false),
|
||||
webpSmartSubsample(false),
|
||||
webpSmartDeblock(false),
|
||||
webpPreset(VIPS_FOREIGN_WEBP_PRESET_DEFAULT),
|
||||
webpEffort(4),
|
||||
webpMinSize(false),
|
||||
|
@ -102,6 +102,29 @@ describe('WebP', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('can produce a different file size using smartDeblock', () =>
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.resize(320, 240)
|
||||
.webp({ quality: 30, smartDeblock: false })
|
||||
.toBuffer()
|
||||
.then(withoutSmartDeblock =>
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.resize(320, 240)
|
||||
.webp({ quality: 30, smartDeblock: true })
|
||||
.toBuffer()
|
||||
.then(withSmartDeblock => {
|
||||
assert.strictEqual(true, withSmartDeblock.length !== withoutSmartDeblock.length);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
it('invalid smartDeblock throws', () => {
|
||||
assert.throws(
|
||||
() => sharp().webp({ smartDeblock: 1 }),
|
||||
/Expected boolean for webpSmartDeblock but received 1 of type number/
|
||||
);
|
||||
});
|
||||
|
||||
it('should produce a different file size with specific preset', () =>
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(320, 240)
|
||||
|
Loading…
x
Reference in New Issue
Block a user