Allow separate parameters for gamma encoding and decoding (#1439)

This commit is contained in:
Daiz 2018-11-11 11:15:38 +02:00 committed by Lovell Fuller
parent 1fa388370e
commit a48f8fbb61
8 changed files with 41 additions and 5 deletions

View File

@ -134,6 +134,7 @@ when applying a gamma correction.
### Parameters
- `gamma` **[Number][1]** value between 1.0 and 3.0. (optional, default `2.2`)
- `gammaOut` ** [Number][1]** value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
- Throws **[Error][5]** Invalid parameters

View File

@ -14,6 +14,10 @@ Requires libvips v8.7.0.
[#1438](https://github.com/lovell/sharp/pull/1438)
[@Daiz](https://github.com/Daiz)
* Add support for different output gamma from what is used for scaling.
[#1439](https://github.com/lovell/sharp/pull/1439)
[@Daiz](https://github.com/Daiz)
#### v0.21.0 - 4<sup>th</sup> October 2018
* Deprecate the following resize-related functions:

View File

@ -136,6 +136,7 @@ const Sharp = function (input, options) {
thresholdGrayscale: true,
trimThreshold: 0,
gamma: 0,
gammaOut: 0,
greyscale: false,
normalise: 0,
booleanBufferIn: null,

View File

@ -189,12 +189,13 @@ function flatten (options) {
* then increasing the encoding (brighten) post-resize at a factor of `gamma`.
* This can improve the perceived brightness of a resized image in non-linear colour spaces.
* JPEG and WebP input images will not take advantage of the shrink-on-load performance optimisation
* when applying a gamma correction.
* when applying a gamma correction. Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases.
* @param {Number} [gamma=2.2] value between 1.0 and 3.0.
* @param {Number} [gammaOut] value between 1.0 and 3.0. Defaults to same as gamma.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function gamma (gamma) {
function gamma (gamma, gammaOut) {
if (!is.defined(gamma)) {
// Default gamma correction of 2.2 (sRGB)
this.options.gamma = 2.2;
@ -203,6 +204,14 @@ function gamma (gamma) {
} else {
throw new Error('Invalid gamma correction (1.0 to 3.0) ' + gamma);
}
if (!is.defined(gammaOut)) {
// Default gamma correction for output is same as input
this.options.gammaOut = this.options.gamma;
} else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) {
this.options.gammaOut = gammaOut;
} else {
throw new Error('Invalid post gamma correction (1.0 to 3.0) ' + gammaOut);
}
return this;
}

View File

@ -612,8 +612,8 @@ class PipelineWorker : public Nan::AsyncWorker {
baton->premultiplied = shouldPremultiplyAlpha;
// Gamma decoding (brighten)
if (baton->gamma >= 1 && baton->gamma <= 3) {
image = sharp::Gamma(image, baton->gamma);
if (baton->gammaOut >= 1 && baton->gammaOut <= 3) {
image = sharp::Gamma(image, baton->gammaOut);
}
// Linear adjustment (a * in + b)
@ -1193,6 +1193,7 @@ NAN_METHOD(pipeline) {
baton->thresholdGrayscale = AttrTo<bool>(options, "thresholdGrayscale");
baton->trimThreshold = AttrTo<double>(options, "trimThreshold");
baton->gamma = AttrTo<double>(options, "gamma");
baton->gammaOut = AttrTo<double>(options, "gammaOut");
baton->linearA = AttrTo<double>(options, "linearA");
baton->linearB = AttrTo<double>(options, "linearB");
baton->greyscale = AttrTo<bool>(options, "greyscale");

View File

@ -87,6 +87,7 @@ struct PipelineBaton {
double linearA;
double linearB;
double gamma;
double gammaOut;
bool greyscale;
bool normalise;
bool useExifOrientation;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -44,6 +44,19 @@ describe('Gamma correction', function () {
});
});
it('input value of 2.2, output value of 3.0', function (done) {
sharp(fixtures.inputJpgWithGammaHoliness)
.resize(129, 111)
.gamma(2.2, 3.0)
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual('jpeg', info.format);
assert.strictEqual(129, info.width);
assert.strictEqual(111, info.height);
fixtures.assertSimilar(fixtures.expected('gamma-in-2.2-out-3.0.jpg'), data, { threshold: 6 }, done);
});
});
it('alpha transparency', function (done) {
sharp(fixtures.inputPngOverlayLayer1)
.resize(320)
@ -57,9 +70,15 @@ describe('Gamma correction', function () {
});
});
it('invalid value', function () {
it('invalid first parameter value', function () {
assert.throws(function () {
sharp(fixtures.inputJpgWithGammaHoliness).gamma(4);
});
});
it('invalid second parameter value', function () {
assert.throws(function () {
sharp(fixtures.inputJpgWithGammaHoliness).gamma(2.2, 4);
});
});
});