mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Ensure rotate-then-extract works with EXIF mirroring #3024
This commit is contained in:
parent
d67e09ba7c
commit
d8f1298511
@ -43,6 +43,9 @@ Requires libvips v8.12.1
|
|||||||
[#3006](https://github.com/lovell/sharp/pull/3006)
|
[#3006](https://github.com/lovell/sharp/pull/3006)
|
||||||
[@christopherbradleybanks](https://github.com/christopherbradleybanks)
|
[@christopherbradleybanks](https://github.com/christopherbradleybanks)
|
||||||
|
|
||||||
|
* Ensure rotate-then-extract works with EXIF mirroring.
|
||||||
|
[#3024](https://github.com/lovell/sharp/issues/3024)
|
||||||
|
|
||||||
## v0.29 - *circle*
|
## v0.29 - *circle*
|
||||||
|
|
||||||
Requires libvips v8.11.3
|
Requires libvips v8.11.3
|
||||||
|
@ -80,13 +80,11 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
|
|
||||||
// Calculate angle of rotation
|
// Calculate angle of rotation
|
||||||
VipsAngle rotation;
|
VipsAngle rotation;
|
||||||
|
bool flip = FALSE;
|
||||||
|
bool flop = FALSE;
|
||||||
if (baton->useExifOrientation) {
|
if (baton->useExifOrientation) {
|
||||||
// Rotate and flip image according to Exif orientation
|
// Rotate and flip image according to Exif orientation
|
||||||
bool flip;
|
|
||||||
bool flop;
|
|
||||||
std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
||||||
baton->flip = baton->flip || flip;
|
|
||||||
baton->flop = baton->flop || flop;
|
|
||||||
} else {
|
} else {
|
||||||
rotation = CalculateAngleRotation(baton->angle);
|
rotation = CalculateAngleRotation(baton->angle);
|
||||||
}
|
}
|
||||||
@ -95,6 +93,14 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
if (baton->rotateBeforePreExtract) {
|
if (baton->rotateBeforePreExtract) {
|
||||||
if (rotation != VIPS_ANGLE_D0) {
|
if (rotation != VIPS_ANGLE_D0) {
|
||||||
image = image.rot(rotation);
|
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);
|
image = sharp::RemoveExifOrientation(image);
|
||||||
}
|
}
|
||||||
if (baton->rotationAngle != 0.0) {
|
if (baton->rotationAngle != 0.0) {
|
||||||
@ -384,20 +390,27 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rotate post-extract 90-angle
|
// Rotate post-extract 90-angle
|
||||||
if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
|
if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
|
||||||
image = image.rot(rotation);
|
image = image.rot(rotation);
|
||||||
image = sharp::RemoveExifOrientation(image);
|
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)
|
// Flip (mirror about Y axis)
|
||||||
if (baton->flip) {
|
if (baton->flip || flip) {
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
image = sharp::RemoveExifOrientation(image);
|
image = sharp::RemoveExifOrientation(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flop (mirror about X axis)
|
// Flop (mirror about X axis)
|
||||||
if (baton->flop) {
|
if (baton->flop || flop) {
|
||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
image = sharp::RemoveExifOrientation(image);
|
image = sharp::RemoveExifOrientation(image);
|
||||||
}
|
}
|
||||||
|
BIN
test/fixtures/expected/rotate-mirror-extract.jpg
vendored
Normal file
BIN
test/fixtures/expected/rotate-mirror-extract.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -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('Invalid parameters', function () {
|
||||||
describe('using the legacy extract(top,left,width,height) syntax', function () {
|
describe('using the legacy extract(top,left,width,height) syntax', function () {
|
||||||
it('String top', function () {
|
it('String top', function () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user