mirror of
https://github.com/lovell/sharp.git
synced 2025-12-06 03:51:40 +01:00
Uses the recommended rules apart from complexity/useArrowFunction, which would affect about 1700 lines of code with little benefit right now. This is something that can be addressed over time.
185 lines
4.4 KiB
JavaScript
185 lines
4.4 KiB
JavaScript
// Copyright 2013 Lovell Fuller and others.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
const sharp = require('../../');
|
|
const assert = require('node:assert');
|
|
const fixtures = require('../fixtures');
|
|
|
|
describe('Modulate', function () {
|
|
describe('Invalid options', function () {
|
|
[
|
|
null,
|
|
undefined,
|
|
10,
|
|
{ brightness: -1 },
|
|
{ brightness: '50%' },
|
|
{ brightness: null },
|
|
{ saturation: -1 },
|
|
{ saturation: '50%' },
|
|
{ saturation: null },
|
|
{ hue: '50deg' },
|
|
{ hue: 1.5 },
|
|
{ hue: null },
|
|
{ lightness: '+50' },
|
|
{ lightness: null }
|
|
].forEach(function (options) {
|
|
it('should throw', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).modulate(options);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should be able to hue-rotate', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ hue: 120 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 41, g: 107, b: 57 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to brighten', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ brightness: 2 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 255, g: 173, b: 168 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to darken', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ brightness: 0.5 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 97, g: 17, b: 25 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to saturate', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ saturation: 2 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 198, g: 0, b: 43 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to desaturate', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ saturation: 0.5 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 127, g: 83, b: 81 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to lighten', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ lightness: 10 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 182, g: 93, b: 92 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to modulate all channels', async () => {
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.modulate({ brightness: 2, saturation: 0.5, hue: 180 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 149, g: 209, b: 214 }, { r, g, b });
|
|
});
|
|
|
|
it('should be able to use linear and modulate together', async () => {
|
|
const contrast = 1.5;
|
|
const brightness = 0.5;
|
|
|
|
const [r, g, b] = await sharp({
|
|
create: {
|
|
width: 1,
|
|
height: 1,
|
|
channels: 3,
|
|
background: { r: 153, g: 68, b: 68 }
|
|
}
|
|
})
|
|
.linear(contrast, -(128 * contrast) + 128)
|
|
.modulate({ brightness })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
assert.deepStrictEqual({ r: 81, g: 0, b: 0 }, { r, g, b });
|
|
});
|
|
|
|
describe('hue-rotate', () => {
|
|
[30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360].forEach(angle => {
|
|
it(`should hue rotate by ${angle} deg`, async () => {
|
|
const base = `modulate-hue-angle-${angle}.png`;
|
|
const actual = fixtures.path(`output.${base}`);
|
|
const expected = fixtures.expected(base);
|
|
|
|
await sharp(fixtures.testPattern)
|
|
.resize(320)
|
|
.modulate({ hue: angle })
|
|
.png({ compressionLevel: 0 })
|
|
.toFile(actual)
|
|
.then(() => {
|
|
fixtures.assertMaxColourDistance(actual, expected, 3);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|