mirror of
https://github.com/lovell/sharp.git
synced 2025-12-06 12:01:41 +01:00
180 lines
5.5 KiB
JavaScript
180 lines
5.5 KiB
JavaScript
/*!
|
||
Copyright 2013 Lovell Fuller and others.
|
||
SPDX-License-Identifier: Apache-2.0
|
||
*/
|
||
|
||
const { describe, it } = require('node:test');
|
||
const assert = require('node:assert');
|
||
const fixtures = require('../fixtures');
|
||
const sharp = require('../../');
|
||
|
||
describe('Alpha transparency', () => {
|
||
it('Flatten to black', (_t, done) => {
|
||
sharp(fixtures.inputPngWithTransparency)
|
||
.flatten()
|
||
.resize(400, 300)
|
||
.toBuffer((err, data, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual(400, info.width);
|
||
assert.strictEqual(300, info.height);
|
||
fixtures.assertSimilar(fixtures.expected('flatten-black.jpg'), data, done);
|
||
});
|
||
});
|
||
|
||
it('Flatten to RGB orange', (_t, done) => {
|
||
sharp(fixtures.inputPngWithTransparency)
|
||
.resize(400, 300)
|
||
.flatten({
|
||
background: { r: 255, g: 102, b: 0 }
|
||
})
|
||
.jpeg({ chromaSubsampling: '4:4:4' })
|
||
.toBuffer((err, data, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual(400, info.width);
|
||
assert.strictEqual(300, info.height);
|
||
fixtures.assertSimilar(fixtures.expected('flatten-orange.jpg'), data, done);
|
||
});
|
||
});
|
||
|
||
it('Flatten to CSS/hex orange', (_t, done) => {
|
||
sharp(fixtures.inputPngWithTransparency)
|
||
.resize(400, 300)
|
||
.flatten({ background: '#ff6600' })
|
||
.jpeg({ chromaSubsampling: '4:4:4' })
|
||
.toBuffer((err, data, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual(400, info.width);
|
||
assert.strictEqual(300, info.height);
|
||
fixtures.assertSimilar(fixtures.expected('flatten-orange.jpg'), data, done);
|
||
});
|
||
});
|
||
|
||
it('Flatten 16-bit PNG with transparency to orange', (_t, done) => {
|
||
const output = fixtures.path('output.flatten-rgb16-orange.jpg');
|
||
sharp(fixtures.inputPngWithTransparency16bit)
|
||
.flatten({
|
||
background: { r: 255, g: 102, b: 0 }
|
||
})
|
||
.toFile(output, (err, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual(true, info.size > 0);
|
||
assert.strictEqual(32, info.width);
|
||
assert.strictEqual(32, info.height);
|
||
fixtures.assertMaxColourDistance(output, fixtures.expected('flatten-rgb16-orange.jpg'), 10);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('Do not flatten', (_t, done) => {
|
||
sharp(fixtures.inputPngWithTransparency)
|
||
.flatten(false)
|
||
.toBuffer((err, _data, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual('png', info.format);
|
||
assert.strictEqual(4, info.channels);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('Ignored for JPEG', (_t, done) => {
|
||
sharp(fixtures.inputJpg)
|
||
.flatten({ background: '#ff0000' })
|
||
.toBuffer((err, _data, info) => {
|
||
if (err) throw err;
|
||
assert.strictEqual('jpeg', info.format);
|
||
assert.strictEqual(3, info.channels);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('Flatten with options but without colour does not throw', () => {
|
||
assert.doesNotThrow(() => {
|
||
sharp().flatten({});
|
||
});
|
||
});
|
||
|
||
it('Flatten to invalid colour throws', () => {
|
||
assert.throws(() => {
|
||
sharp().flatten({ background: 1 });
|
||
});
|
||
});
|
||
|
||
it('Enlargement with non-nearest neighbor interpolation shouldn’t cause dark edges', () => {
|
||
const base = 'alpha-premultiply-enlargement-2048x1536-paper.png';
|
||
const actual = fixtures.path(`output.${base}`);
|
||
const expected = fixtures.expected(base);
|
||
return sharp(fixtures.inputPngAlphaPremultiplicationSmall)
|
||
.resize(2048, 1536)
|
||
.toFile(actual)
|
||
.then(() => {
|
||
fixtures.assertMaxColourDistance(actual, expected, 102);
|
||
});
|
||
});
|
||
|
||
it('Reduction with non-nearest neighbor interpolation shouldn’t cause dark edges', () => {
|
||
const base = 'alpha-premultiply-reduction-1024x768-paper.png';
|
||
const actual = fixtures.path(`output.${base}`);
|
||
const expected = fixtures.expected(base);
|
||
return sharp(fixtures.inputPngAlphaPremultiplicationLarge)
|
||
.resize(1024, 768)
|
||
.toFile(actual)
|
||
.then(() => {
|
||
fixtures.assertMaxColourDistance(actual, expected, 102);
|
||
});
|
||
});
|
||
|
||
it('Removes alpha from fixtures with transparency, ignores those without', () => Promise.all([
|
||
fixtures.inputPngWithTransparency,
|
||
fixtures.inputPngWithTransparency16bit,
|
||
fixtures.inputWebPWithTransparency,
|
||
fixtures.inputJpg,
|
||
fixtures.inputPng,
|
||
fixtures.inputWebP
|
||
].map((input) => sharp(input)
|
||
.resize(10)
|
||
.removeAlpha()
|
||
.toBuffer({ resolveWithObject: true })
|
||
.then((result) => {
|
||
assert.strictEqual(3, result.info.channels);
|
||
}))));
|
||
|
||
it('Ensures alpha from fixtures without transparency, ignores those with', () => Promise.all([
|
||
fixtures.inputPngWithTransparency,
|
||
fixtures.inputPngWithTransparency16bit,
|
||
fixtures.inputWebPWithTransparency,
|
||
fixtures.inputJpg,
|
||
fixtures.inputPng,
|
||
fixtures.inputWebP
|
||
].map((input) => sharp(input)
|
||
.resize(10)
|
||
.ensureAlpha()
|
||
.png()
|
||
.toBuffer({ resolveWithObject: true })
|
||
.then((result) => {
|
||
assert.strictEqual(4, result.info.channels);
|
||
}))));
|
||
|
||
it('Valid ensureAlpha value used for alpha channel', async () => {
|
||
const background = { r: 255, g: 0, b: 0 };
|
||
const [r, g, b, alpha] = await sharp({
|
||
create: {
|
||
width: 8,
|
||
height: 8,
|
||
channels: 3,
|
||
background
|
||
}
|
||
})
|
||
.ensureAlpha(0.5)
|
||
.raw()
|
||
.toBuffer();
|
||
|
||
assert.deepStrictEqual({ r, g, b, alpha }, { ...background, alpha: 127 });
|
||
});
|
||
|
||
it('Invalid ensureAlpha value throws', async () => {
|
||
assert.throws(() => {
|
||
sharp().ensureAlpha('fail');
|
||
});
|
||
});
|
||
});
|