Tests: refactor modulate suite, ~20x faster
BIN
test/fixtures/expected/modulate-all.jpg
vendored
Before Width: | Height: | Size: 664 KiB |
BIN
test/fixtures/expected/modulate-brightness-0-5.jpg
vendored
Before Width: | Height: | Size: 426 KiB |
BIN
test/fixtures/expected/modulate-brightness-2.jpg
vendored
Before Width: | Height: | Size: 692 KiB |
BIN
test/fixtures/expected/modulate-hue-120.jpg
vendored
Before Width: | Height: | Size: 653 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-120.png
vendored
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 29 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-150.png
vendored
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-180.png
vendored
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 29 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-210.png
vendored
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 29 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-240.png
vendored
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-270.png
vendored
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-30.png
vendored
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-300.png
vendored
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-330.png
vendored
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-360.png
vendored
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 32 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-60.png
vendored
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/modulate-hue-angle-90.png
vendored
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 29 KiB |
BIN
test/fixtures/expected/modulate-linear.jpg
vendored
Before Width: | Height: | Size: 62 KiB |
BIN
test/fixtures/expected/modulate-saturation-0.5.jpg
vendored
Before Width: | Height: | Size: 606 KiB |
BIN
test/fixtures/expected/modulate-saturation-2.jpg
vendored
Before Width: | Height: | Size: 672 KiB |
@ -28,115 +28,138 @@ describe('Modulate', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to hue-rotate', function () {
|
it('should be able to hue-rotate', async () => {
|
||||||
const base = 'modulate-hue-120.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ hue: 120 })
|
.modulate({ hue: 120 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 41, g: 107, b: 57 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to brighten', function () {
|
it('should be able to brighten', async () => {
|
||||||
const base = 'modulate-brightness-2.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ brightness: 2 })
|
.modulate({ brightness: 2 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 255, g: 173, b: 168 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to unbrighten', function () {
|
it('should be able to darken', async () => {
|
||||||
const base = 'modulate-brightness-0-5.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ brightness: 0.5 })
|
.modulate({ brightness: 0.5 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 97, g: 17, b: 25 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to saturate', function () {
|
it('should be able to saturate', async () => {
|
||||||
const base = 'modulate-saturation-2.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ saturation: 2 })
|
.modulate({ saturation: 2 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 30);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 198, g: 0, b: 43 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to desaturate', function () {
|
it('should be able to desaturate', async () => {
|
||||||
const base = 'modulate-saturation-0.5.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ saturation: 0.5 })
|
.modulate({ saturation: 0.5 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 127, g: 83, b: 81 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to modulate all channels', function () {
|
it('should be able to modulate all channels', async () => {
|
||||||
const base = 'modulate-all.jpg';
|
const [r, g, b] = await sharp({
|
||||||
const actual = fixtures.path('output.' + base);
|
create: {
|
||||||
const expected = fixtures.expected(base);
|
width: 1,
|
||||||
|
height: 1,
|
||||||
return sharp(fixtures.inputJpg)
|
channels: 3,
|
||||||
|
background: { r: 153, g: 68, b: 68 }
|
||||||
|
}
|
||||||
|
})
|
||||||
.modulate({ brightness: 2, saturation: 0.5, hue: 180 })
|
.modulate({ brightness: 2, saturation: 0.5, hue: 180 })
|
||||||
.toFile(actual)
|
.raw()
|
||||||
.then(function () {
|
.toBuffer();
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
|
||||||
});
|
assert.deepStrictEqual({ r: 149, g: 209, b: 214 }, { r, g, b });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hue-rotate', function (done) {
|
it('should be able to use linear and modulate together', async () => {
|
||||||
[30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360].forEach(function (angle) {
|
const contrast = 1.5;
|
||||||
it('should properly hue rotate by ' + angle + 'deg', function () {
|
const brightness = 0.5;
|
||||||
const base = 'modulate-hue-angle-' + angle + '.png';
|
|
||||||
const actual = fixtures.path('output.' + base);
|
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);
|
const expected = fixtures.expected(base);
|
||||||
|
|
||||||
return sharp(fixtures.testPattern)
|
await sharp(fixtures.testPattern)
|
||||||
|
.resize(320)
|
||||||
.modulate({ hue: angle })
|
.modulate({ hue: angle })
|
||||||
|
.png({ compressionLevel: 0 })
|
||||||
.toFile(actual)
|
.toFile(actual)
|
||||||
.then(function () {
|
.then(() => {
|
||||||
fixtures.assertMaxColourDistance(actual, expected, 25);
|
fixtures.assertMaxColourDistance(actual, expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to use linear and modulate together', function () {
|
|
||||||
const base = 'modulate-linear.jpg';
|
|
||||||
const actual = fixtures.path('output.' + base);
|
|
||||||
const expected = fixtures.expected(base);
|
|
||||||
|
|
||||||
const contrast = 1.5;
|
|
||||||
const brightness = 0.5;
|
|
||||||
|
|
||||||
return sharp(fixtures.testPattern)
|
|
||||||
.linear(contrast, -(128 * contrast) + 128)
|
|
||||||
.modulate({ brightness })
|
|
||||||
.toFile(actual)
|
|
||||||
.then(function () {
|
|
||||||
fixtures.assertMaxColourDistance(actual, expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|