mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Ensure manual flip, rotate, resize op order #3391
This commit is contained in:
parent
99bf279de8
commit
eacb8337fa
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
Requires libvips v8.13.2
|
Requires libvips v8.13.2
|
||||||
|
|
||||||
|
### v0.31.2 - TBD
|
||||||
|
|
||||||
|
* Ensure manual flip, rotate, resize operation ordering (regression in 0.31.1)
|
||||||
|
[#3391](https://github.com/lovell/sharp/issues/3391)
|
||||||
|
|
||||||
### 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.
|
||||||
|
@ -81,35 +81,47 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
int pageHeight = sharp::GetPageHeight(image);
|
int pageHeight = sharp::GetPageHeight(image);
|
||||||
|
|
||||||
// Calculate angle of rotation
|
// Calculate angle of rotation
|
||||||
VipsAngle rotation;
|
VipsAngle rotation = VIPS_ANGLE_D0;
|
||||||
bool flip = FALSE;
|
VipsAngle autoRotation = VIPS_ANGLE_D0;
|
||||||
bool flop = FALSE;
|
bool autoFlip = FALSE;
|
||||||
|
bool autoFlop = FALSE;
|
||||||
if (baton->useExifOrientation) {
|
if (baton->useExifOrientation) {
|
||||||
// Rotate and flip image according to Exif orientation
|
// Rotate and flip image according to Exif orientation
|
||||||
std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
std::tie(autoRotation, autoFlip, autoFlop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
||||||
|
image = sharp::RemoveExifOrientation(image);
|
||||||
} else {
|
} else {
|
||||||
rotation = CalculateAngleRotation(baton->angle);
|
rotation = CalculateAngleRotation(baton->angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate pre-extract
|
// Rotate pre-extract
|
||||||
bool const shouldRotateBefore = baton->rotateBeforePreExtract &&
|
bool const shouldRotateBefore = baton->rotateBeforePreExtract &&
|
||||||
(rotation != VIPS_ANGLE_D0 || flip || flop || baton->rotationAngle != 0.0);
|
(rotation != VIPS_ANGLE_D0 || autoRotation != VIPS_ANGLE_D0 ||
|
||||||
|
autoFlip || baton->flip || autoFlop || baton->flop ||
|
||||||
|
baton->rotationAngle != 0.0);
|
||||||
|
|
||||||
if (shouldRotateBefore) {
|
if (shouldRotateBefore) {
|
||||||
|
if (autoRotation != VIPS_ANGLE_D0) {
|
||||||
|
image = image.rot(autoRotation);
|
||||||
|
autoRotation = VIPS_ANGLE_D0;
|
||||||
|
}
|
||||||
|
if (autoFlip) {
|
||||||
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
|
autoFlip = FALSE;
|
||||||
|
} else if (baton->flip) {
|
||||||
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
|
baton->flip = FALSE;
|
||||||
|
}
|
||||||
|
if (autoFlop) {
|
||||||
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
|
autoFlop = FALSE;
|
||||||
|
} else if (baton->flop) {
|
||||||
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
|
baton->flop = FALSE;
|
||||||
|
}
|
||||||
if (rotation != VIPS_ANGLE_D0) {
|
if (rotation != VIPS_ANGLE_D0) {
|
||||||
image = image.rot(rotation);
|
image = image.rot(rotation);
|
||||||
|
rotation = VIPS_ANGLE_D0;
|
||||||
}
|
}
|
||||||
if (flip) {
|
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
|
||||||
}
|
|
||||||
if (flop) {
|
|
||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
|
||||||
}
|
|
||||||
if (rotation != VIPS_ANGLE_D0 || flip || flop) {
|
|
||||||
image = sharp::RemoveExifOrientation(image);
|
|
||||||
}
|
|
||||||
flop = FALSE;
|
|
||||||
flip = FALSE;
|
|
||||||
if (baton->rotationAngle != 0.0) {
|
if (baton->rotationAngle != 0.0) {
|
||||||
MultiPageUnsupported(nPages, "Rotate");
|
MultiPageUnsupported(nPages, "Rotate");
|
||||||
std::vector<double> background;
|
std::vector<double> background;
|
||||||
@ -368,29 +380,16 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flip (mirror about Y axis)
|
// Flip (mirror about Y axis)
|
||||||
if (baton->flip || flip) {
|
if (baton->flip || autoFlip) {
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
||||||
image = sharp::RemoveExifOrientation(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flop (mirror about X axis)
|
// Flop (mirror about X axis)
|
||||||
if (baton->flop || flop) {
|
if (baton->flop || autoFlop) {
|
||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||||
image = sharp::RemoveExifOrientation(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
if (flip) {
|
|
||||||
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
|
||||||
flip = FALSE;
|
|
||||||
}
|
|
||||||
if (flop) {
|
|
||||||
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
|
|
||||||
flop = FALSE;
|
|
||||||
}
|
|
||||||
image = sharp::RemoveExifOrientation(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join additional color channels to the image
|
// Join additional color channels to the image
|
||||||
|
@ -418,4 +418,29 @@ describe('Rotation', function () {
|
|||||||
assert.strictEqual(g, 73);
|
assert.strictEqual(g, 73);
|
||||||
assert.strictEqual(b, 52);
|
assert.strictEqual(b, 52);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Flip and rotate ordering', async () => {
|
||||||
|
const [r, g, b] = await sharp(fixtures.inputJpgWithPortraitExif5)
|
||||||
|
.flip()
|
||||||
|
.rotate(90)
|
||||||
|
.raw()
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
assert.strictEqual(r, 55);
|
||||||
|
assert.strictEqual(g, 65);
|
||||||
|
assert.strictEqual(b, 31);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Flip, rotate and resize ordering', async () => {
|
||||||
|
const [r, g, b] = await sharp(fixtures.inputJpgWithPortraitExif5)
|
||||||
|
.flip()
|
||||||
|
.rotate(90)
|
||||||
|
.resize(449)
|
||||||
|
.raw()
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
assert.strictEqual(r, 54);
|
||||||
|
assert.strictEqual(g, 64);
|
||||||
|
assert.strictEqual(b, 30);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user