diff --git a/docs/changelog.md b/docs/changelog.md index 392c3ad1..d3692416 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -14,6 +14,9 @@ Requires libvips v8.9.1 * Add support for 32-bit Windows. [#2088](https://github.com/lovell/sharp/issues/2088) +* Ensure correct ordering of rotate-then-trim operations. + [#2087](https://github.com/lovell/sharp/issues/2087) + ## v0.24 - "*wit*" Requires libvips v8.9.0. diff --git a/lib/resize.js b/lib/resize.js index 13e881fd..1ccc6e09 100644 --- a/lib/resize.js +++ b/lib/resize.js @@ -85,6 +85,13 @@ const mapFitToCanvas = { outside: 'min' }; +/** + * @private + */ +function isRotationExpected (options) { + return (options.angle % 360) !== 0 || options.useExifOrientation === true || options.rotationAngle !== 0; +} + /** * Resize image to `width`, `height` or `width x height`. * @@ -367,7 +374,7 @@ function extract (options) { } }, this); // Ensure existing rotation occurs before pre-resize extraction - if (suffix === 'Pre' && ((this.options.angle % 360) !== 0 || this.options.useExifOrientation === true || this.options.rotationAngle !== 0)) { + if (suffix === 'Pre' && isRotationExpected(this.options)) { this.options.rotateBeforePreExtract = true; } return this; @@ -391,6 +398,9 @@ function trim (threshold) { } else { throw is.invalidParameterError('threshold', 'number greater than zero', threshold); } + if (this.options.trimThreshold && isRotationExpected(this.options)) { + this.options.rotateBeforePreExtract = true; + } return this; } diff --git a/test/unit/trim.js b/test/unit/trim.js index 118876b9..2591c013 100644 --- a/test/unit/trim.js +++ b/test/unit/trim.js @@ -94,6 +94,32 @@ describe('Trim borders', function () { .catch(done); }); + it('should rotate before trim', () => + sharp({ + create: { + width: 20, + height: 30, + channels: 3, + background: 'white' + } + }) + .rotate(30) + .png() + .toBuffer() + .then(rotated30 => + sharp(rotated30) + .rotate(-30) + .trim(128) + .toBuffer({ resolveWithObject: true }) + .then(({ info }) => { + assert.strictEqual(20, info.width); + assert.strictEqual(31, info.height); + assert.strictEqual(-8, info.trimOffsetTop); + assert.strictEqual(-13, info.trimOffsetLeft); + }) + ) + ); + describe('Invalid thresholds', function () { [-1, 'fail', {}].forEach(function (threshold) { it(JSON.stringify(threshold), function () {