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.
333 lines
11 KiB
JavaScript
333 lines
11 KiB
JavaScript
// Copyright 2013 Lovell Fuller and others.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
const assert = require('node:assert');
|
|
|
|
const sharp = require('../../');
|
|
const fixtures = require('../fixtures');
|
|
|
|
describe('Partial image extraction', function () {
|
|
it('JPEG', function (done) {
|
|
sharp(fixtures.inputJpg)
|
|
.extract({ left: 2, top: 2, width: 20, height: 20 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(20, info.width);
|
|
assert.strictEqual(20, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('PNG', function (done) {
|
|
sharp(fixtures.inputPng)
|
|
.extract({ left: 200, top: 300, width: 400, height: 200 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(400, info.width);
|
|
assert.strictEqual(200, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract.png'), data, done);
|
|
});
|
|
});
|
|
|
|
it('WebP', function (done) {
|
|
sharp(fixtures.inputWebP)
|
|
.extract({ left: 100, top: 50, width: 125, height: 200 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(125, info.width);
|
|
assert.strictEqual(200, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract.webp'), data, done);
|
|
});
|
|
});
|
|
|
|
describe('Animated WebP', function () {
|
|
it('Before resize', function (done) {
|
|
sharp(fixtures.inputWebPAnimated, { pages: -1 })
|
|
.extract({ left: 0, top: 30, width: 80, height: 20 })
|
|
.resize(320, 80)
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80 * 9, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('gravity-center-height.webp'), data, done);
|
|
});
|
|
});
|
|
|
|
it('After resize', function (done) {
|
|
sharp(fixtures.inputWebPAnimated, { pages: -1 })
|
|
.resize(320, 320)
|
|
.extract({ left: 0, top: 120, width: 320, height: 80 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(320, info.width);
|
|
assert.strictEqual(80 * 9, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('gravity-center-height.webp'), data, done);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('TIFF', function (done) {
|
|
sharp(fixtures.inputTiff)
|
|
.extract({ left: 34, top: 63, width: 341, height: 529 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(341, info.width);
|
|
assert.strictEqual(529, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract.tiff'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Before resize', function (done) {
|
|
sharp(fixtures.inputJpg)
|
|
.extract({ left: 10, top: 10, width: 10, height: 500 })
|
|
.resize(100, 100)
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(100, info.width);
|
|
assert.strictEqual(100, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract-resize.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('After resize and crop', function (done) {
|
|
sharp(fixtures.inputJpg)
|
|
.resize(500, 500, {
|
|
position: sharp.gravity.north
|
|
})
|
|
.extract({ left: 10, top: 10, width: 100, height: 100 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(100, info.width);
|
|
assert.strictEqual(100, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('resize-crop-extract.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Before and after resize and crop', function (done) {
|
|
sharp(fixtures.inputJpg)
|
|
.extract({ left: 0, top: 0, width: 700, height: 700 })
|
|
.resize(500, 500, {
|
|
position: sharp.gravity.north
|
|
})
|
|
.extract({ left: 10, top: 10, width: 100, height: 100 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(100, info.width);
|
|
assert.strictEqual(100, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract-resize-crop-extract.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Extract then rotate', function (done) {
|
|
sharp(fixtures.inputPngWithGreyAlpha)
|
|
.extract({ left: 20, top: 10, width: 380, height: 280 })
|
|
.rotate(90)
|
|
.jpeg()
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(280, info.width);
|
|
assert.strictEqual(380, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract-rotate.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Rotate then extract', function (done) {
|
|
sharp(fixtures.inputPngWithGreyAlpha)
|
|
.rotate(90)
|
|
.extract({ left: 20, top: 10, width: 280, height: 380 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(280, info.width);
|
|
assert.strictEqual(380, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('rotate-extract.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Extract then rotate then extract', function (done) {
|
|
sharp(fixtures.inputPngWithGreyAlpha)
|
|
.extract({ left: 20, top: 10, width: 180, height: 280 })
|
|
.rotate(90)
|
|
.extract({ left: 20, top: 10, width: 200, height: 100 })
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(200, info.width);
|
|
assert.strictEqual(100, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract-rotate-extract.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Extract then rotate non-90 anagle', function (done) {
|
|
sharp(fixtures.inputPngWithGreyAlpha)
|
|
.extract({ left: 20, top: 10, width: 380, height: 280 })
|
|
.rotate(45)
|
|
.jpeg()
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(467, info.width);
|
|
assert.strictEqual(467, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('extract-rotate-45.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
it('Rotate then extract non-90 angle', function (done) {
|
|
sharp(fixtures.inputPngWithGreyAlpha)
|
|
.rotate(45)
|
|
.extract({ left: 20, top: 10, width: 380, height: 280 })
|
|
.jpeg()
|
|
.toBuffer(function (err, data, info) {
|
|
if (err) throw err;
|
|
assert.strictEqual(380, info.width);
|
|
assert.strictEqual(280, info.height);
|
|
fixtures.assertSimilar(fixtures.expected('rotate-extract-45.jpg'), data, done);
|
|
});
|
|
});
|
|
|
|
describe('Apply exif orientation and mirroring then extract', () => {
|
|
[
|
|
{
|
|
name: 'EXIF-1',
|
|
image: fixtures.inputJpgWithLandscapeExif1
|
|
},
|
|
{
|
|
name: 'EXIF-2',
|
|
image: fixtures.inputJpgWithLandscapeExif2
|
|
},
|
|
{
|
|
name: 'EXIF-3',
|
|
image: fixtures.inputJpgWithLandscapeExif3
|
|
},
|
|
{
|
|
name: 'EXIF-4',
|
|
image: fixtures.inputJpgWithLandscapeExif4
|
|
},
|
|
{
|
|
name: 'EXIF-5',
|
|
image: fixtures.inputJpgWithLandscapeExif5
|
|
},
|
|
{
|
|
name: 'EXIF-6',
|
|
image: fixtures.inputJpgWithLandscapeExif6
|
|
},
|
|
{
|
|
name: 'EXIF-7',
|
|
image: fixtures.inputJpgWithLandscapeExif7
|
|
},
|
|
{
|
|
name: 'EXIF-8',
|
|
image: fixtures.inputJpgWithLandscapeExif8
|
|
}
|
|
].forEach(({ name, image }) => {
|
|
it(name, function (done) {
|
|
sharp(image)
|
|
.rotate()
|
|
.extract({ left: 0, top: 208, width: 60, height: 40 })
|
|
.toBuffer(function (err, data) {
|
|
if (err) throw err;
|
|
fixtures.assertSimilar(fixtures.expected('rotate-mirror-extract.jpg'), data, done);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Invalid parameters', function () {
|
|
describe('using the legacy extract(top,left,width,height) syntax', function () {
|
|
it('String top', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract('spoons', 10, 10, 10);
|
|
});
|
|
});
|
|
|
|
it('Non-integral left', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract(10, 10.2, 10, 10);
|
|
});
|
|
});
|
|
|
|
it('Negative width - negative', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract(10, 10, -10, 10);
|
|
});
|
|
});
|
|
|
|
it('Null height', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract(10, 10, 10, null);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Undefined', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract();
|
|
});
|
|
});
|
|
|
|
it('String top', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract({ left: 10, top: 'spoons', width: 10, height: 10 });
|
|
});
|
|
});
|
|
|
|
it('Non-integral left', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract({ left: 10.2, top: 10, width: 10, height: 10 });
|
|
});
|
|
});
|
|
|
|
it('Negative width - negative', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract({ left: 10, top: 10, width: -10, height: 10 });
|
|
});
|
|
});
|
|
|
|
it('Null height', function () {
|
|
assert.throws(function () {
|
|
sharp(fixtures.inputJpg).extract({ left: 10, top: 10, width: 10, height: null });
|
|
});
|
|
});
|
|
|
|
it('Bad image area', function (done) {
|
|
sharp(fixtures.inputJpg)
|
|
.extract({ left: 3000, top: 10, width: 10, height: 10 })
|
|
.toBuffer(function (err) {
|
|
assert(err instanceof Error);
|
|
assert.strictEqual(err.message, 'extract_area: bad extract area');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Multiple extract emits warning', () => {
|
|
let warningMessage = '';
|
|
const s = sharp();
|
|
s.on('warning', function (msg) { warningMessage = msg; });
|
|
const options = { top: 0, left: 0, width: 1, height: 1 };
|
|
s.extract(options).extract(options);
|
|
assert.strictEqual(warningMessage, '');
|
|
s.extract(options);
|
|
assert.strictEqual(warningMessage, 'ignoring previous extract options');
|
|
});
|
|
|
|
it('Multiple rotate+extract emits warning', () => {
|
|
let warningMessage = '';
|
|
const s = sharp().rotate();
|
|
s.on('warning', function (msg) { warningMessage = msg; });
|
|
const options = { top: 0, left: 0, width: 1, height: 1 };
|
|
s.extract(options).extract(options);
|
|
assert.strictEqual(warningMessage, '');
|
|
s.extract(options);
|
|
assert.strictEqual(warningMessage, 'ignoring previous extract options');
|
|
});
|
|
|
|
it('Multiple extract+resize emits warning', () => {
|
|
let warningMessage = '';
|
|
const s = sharp();
|
|
s.on('warning', function (msg) { warningMessage = msg; });
|
|
const options = { top: 0, left: 0, width: 1, height: 1 };
|
|
s.extract(options).extract(options);
|
|
assert.strictEqual(warningMessage, '');
|
|
s.resize(1);
|
|
assert.strictEqual(warningMessage, 'operation order will be: extract, resize, extract');
|
|
});
|
|
});
|
|
});
|