Ensure rotate-then-extract works with EXIF mirroring #3024

This commit is contained in:
Lovell Fuller 2022-01-08 18:48:11 +00:00
parent d67e09ba7c
commit d8f1298511
4 changed files with 36 additions and 10 deletions

View File

@ -43,6 +43,9 @@ Requires libvips v8.12.1
[#3006](https://github.com/lovell/sharp/pull/3006)
[@christopherbradleybanks](https://github.com/christopherbradleybanks)
* Ensure rotate-then-extract works with EXIF mirroring.
[#3024](https://github.com/lovell/sharp/issues/3024)
## v0.29 - *circle*
Requires libvips v8.11.3

View File

@ -80,13 +80,11 @@ class PipelineWorker : public Napi::AsyncWorker {
// Calculate angle of rotation
VipsAngle rotation;
bool flip = FALSE;
bool flop = FALSE;
if (baton->useExifOrientation) {
// Rotate and flip image according to Exif orientation
bool flip;
bool flop;
std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
baton->flip = baton->flip || flip;
baton->flop = baton->flop || flop;
} else {
rotation = CalculateAngleRotation(baton->angle);
}
@ -95,6 +93,14 @@ class PipelineWorker : public Napi::AsyncWorker {
if (baton->rotateBeforePreExtract) {
if (rotation != VIPS_ANGLE_D0) {
image = image.rot(rotation);
if (flip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
flip = FALSE;
}
if (flop) {
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
flop = FALSE;
}
image = sharp::RemoveExifOrientation(image);
}
if (baton->rotationAngle != 0.0) {
@ -384,20 +390,27 @@ class PipelineWorker : public Napi::AsyncWorker {
}
// Rotate post-extract 90-angle
if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
image = image.rot(rotation);
image = sharp::RemoveExifOrientation(image);
if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
image = image.rot(rotation);
if (flip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
flip = FALSE;
}
if (flop) {
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
flop = FALSE;
}
image = sharp::RemoveExifOrientation(image);
}
// Flip (mirror about Y axis)
if (baton->flip) {
if (baton->flip || flip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
image = sharp::RemoveExifOrientation(image);
}
// Flop (mirror about X axis)
if (baton->flop) {
if (baton->flop || flop) {
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
image = sharp::RemoveExifOrientation(image);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -168,6 +168,16 @@ describe('Partial image extraction', function () {
});
});
it('Rotate with EXIF mirroring then extract', function (done) {
sharp(fixtures.inputJpgWithLandscapeExif7)
.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 () {