mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Ensure auto-rotate always works without resize #3422
This commit is contained in:
parent
37f7ccfff4
commit
5b0fba4c01
@ -9,6 +9,9 @@ Requires libvips v8.13.2
|
|||||||
* Ensure manual flip, rotate, resize operation ordering (regression in 0.31.1)
|
* Ensure manual flip, rotate, resize operation ordering (regression in 0.31.1)
|
||||||
[#3391](https://github.com/lovell/sharp/issues/3391)
|
[#3391](https://github.com/lovell/sharp/issues/3391)
|
||||||
|
|
||||||
|
* Ensure auto-rotation works without resize (regression in 0.31.1)
|
||||||
|
[#3422](https://github.com/lovell/sharp/issues/3422)
|
||||||
|
|
||||||
### v0.31.1 - 29th September 2022
|
### v0.31.1 - 29th September 2022
|
||||||
|
|
||||||
* Upgrade to libvips v8.13.2 for upstream bug fixes.
|
* Upgrade to libvips v8.13.2 for upstream bug fixes.
|
||||||
|
@ -162,7 +162,9 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
int targetResizeHeight = baton->height;
|
int targetResizeHeight = baton->height;
|
||||||
|
|
||||||
// Swap input output width and height when rotating by 90 or 270 degrees
|
// Swap input output width and height when rotating by 90 or 270 degrees
|
||||||
bool swap = !baton->rotateBeforePreExtract && (rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270);
|
bool swap = !baton->rotateBeforePreExtract &&
|
||||||
|
(rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270 ||
|
||||||
|
autoRotation == VIPS_ANGLE_D90 || autoRotation == VIPS_ANGLE_D270);
|
||||||
|
|
||||||
// Shrink to pageHeight, so we work for multi-page images
|
// Shrink to pageHeight, so we work for multi-page images
|
||||||
std::tie(hshrink, vshrink) = sharp::ResolveShrink(
|
std::tie(hshrink, vshrink) = sharp::ResolveShrink(
|
||||||
@ -379,6 +381,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
->set("kernel", baton->kernel));
|
->set("kernel", baton->kernel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-rotate post-extract
|
||||||
|
if (autoRotation != VIPS_ANGLE_D0) {
|
||||||
|
image = image.rot(autoRotation);
|
||||||
|
}
|
||||||
// Flip (mirror about Y axis)
|
// Flip (mirror about Y axis)
|
||||||
if (baton->flip || autoFlip) {
|
if (baton->flip || autoFlip) {
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
@ -388,7 +394,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
}
|
}
|
||||||
// Rotate post-extract 90-angle
|
// Rotate post-extract 90-angle
|
||||||
if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
|
if (rotation != VIPS_ANGLE_D0) {
|
||||||
image = image.rot(rotation);
|
image = image.rot(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,16 +8,43 @@ const fixtures = require('../fixtures');
|
|||||||
describe('Rotation', function () {
|
describe('Rotation', function () {
|
||||||
['Landscape', 'Portrait'].forEach(function (orientation) {
|
['Landscape', 'Portrait'].forEach(function (orientation) {
|
||||||
[1, 2, 3, 4, 5, 6, 7, 8].forEach(function (exifTag) {
|
[1, 2, 3, 4, 5, 6, 7, 8].forEach(function (exifTag) {
|
||||||
it('Input image has Orientation EXIF tag value of (' + exifTag + '), auto-rotate', function (done) {
|
const input = fixtures[`inputJpgWith${orientation}Exif${exifTag}`];
|
||||||
sharp(fixtures['inputJpgWith' + orientation + 'Exif' + exifTag])
|
const expectedOutput = fixtures.expected(`${orientation}_${exifTag}-out.jpg`);
|
||||||
|
it(`Auto-rotate ${orientation} image with EXIF Orientation ${exifTag}`, function (done) {
|
||||||
|
const [expectedWidth, expectedHeight] = orientation === 'Landscape' ? [600, 450] : [450, 600];
|
||||||
|
sharp(input)
|
||||||
.rotate()
|
.rotate()
|
||||||
.resize(320)
|
|
||||||
.toBuffer(function (err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('jpeg', info.format);
|
assert.strictEqual(info.width, expectedWidth);
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(info.height, expectedHeight);
|
||||||
assert.strictEqual(orientation === 'Landscape' ? 240 : 427, info.height);
|
fixtures.assertSimilar(expectedOutput, data, done);
|
||||||
fixtures.assertSimilar(fixtures.expected(orientation + '_' + exifTag + '-out.jpg'), data, done);
|
});
|
||||||
|
});
|
||||||
|
it(`Auto-rotate then resize ${orientation} image with EXIF Orientation ${exifTag}`, function (done) {
|
||||||
|
const [expectedWidth, expectedHeight] = orientation === 'Landscape' ? [320, 240] : [320, 427];
|
||||||
|
sharp(input)
|
||||||
|
.rotate()
|
||||||
|
.resize({ width: 320 })
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(info.width, expectedWidth);
|
||||||
|
assert.strictEqual(info.height, expectedHeight);
|
||||||
|
fixtures.assertSimilar(expectedOutput, data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it(`Resize then auto-rotate ${orientation} image with EXIF Orientation ${exifTag}`, function (done) {
|
||||||
|
const [expectedWidth, expectedHeight] = orientation === 'Landscape'
|
||||||
|
? (exifTag < 5) ? [320, 240] : [320, 240]
|
||||||
|
: [320, 427];
|
||||||
|
sharp(input)
|
||||||
|
.resize({ width: 320 })
|
||||||
|
.rotate()
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(info.width, expectedWidth);
|
||||||
|
assert.strictEqual(info.height, expectedHeight);
|
||||||
|
fixtures.assertSimilar(expectedOutput, data, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user