Add autoOrient operation and constructor option #4144

This commit is contained in:
Don Denton
2024-07-03 10:34:54 -04:00
committed by Lovell Fuller
parent b7ff2645c4
commit 14c83e1f4c
137 changed files with 428 additions and 136 deletions

View File

@@ -63,14 +63,14 @@ class PipelineWorker : public Napi::AsyncWorker {
bool autoFlip = false;
bool autoFlop = false;
if (baton->useExifOrientation) {
if (baton->input->autoOrient) {
// Rotate and flip image according to Exif orientation
std::tie(autoRotation, autoFlip, autoFlop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
image = sharp::RemoveExifOrientation(image);
} else {
rotation = CalculateAngleRotation(baton->angle);
}
rotation = CalculateAngleRotation(baton->angle);
// Rotate pre-extract
bool const shouldRotateBefore = baton->rotateBeforePreExtract &&
(rotation != VIPS_ANGLE_D0 || autoRotation != VIPS_ANGLE_D0 ||
@@ -92,18 +92,14 @@ class PipelineWorker : public Napi::AsyncWorker {
image = image.rot(autoRotation);
autoRotation = VIPS_ANGLE_D0;
}
if (autoFlip) {
if (autoFlip != baton->flip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
autoFlip = false;
} else if (baton->flip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
baton->flip = false;
}
if (autoFlop) {
if (autoFlop != baton->flop) {
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) {
@@ -396,11 +392,11 @@ class PipelineWorker : public Napi::AsyncWorker {
image = image.rot(autoRotation);
}
// Mirror vertically (up-down) about the x-axis
if (baton->flip || autoFlip) {
if (baton->flip != autoFlip) {
image = image.flip(VIPS_DIRECTION_VERTICAL);
}
// Mirror horizontally (left-right) about the y-axis
if (baton->flop || autoFlop) {
if (baton->flop != autoFlop) {
image = image.flip(VIPS_DIRECTION_HORIZONTAL);
}
// Rotate post-extract 90-angle
@@ -631,6 +627,30 @@ class PipelineWorker : public Napi::AsyncWorker {
composite->input->access = access;
std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input);
compositeImage = sharp::EnsureColourspace(compositeImage, baton->colourspacePipeline);
if (composite->input->autoOrient) {
// Respect EXIF Orientation
VipsAngle compositeAutoRotation = VIPS_ANGLE_D0;
bool compositeAutoFlip = false;
bool compositeAutoFlop = false;
std::tie(compositeAutoRotation, compositeAutoFlip, compositeAutoFlop) =
CalculateExifRotationAndFlip(sharp::ExifOrientation(compositeImage));
compositeImage = sharp::RemoveExifOrientation(compositeImage);
compositeImage = sharp::StaySequential(compositeImage,
compositeAutoRotation != VIPS_ANGLE_D0 || compositeAutoFlip);
if (compositeAutoRotation != VIPS_ANGLE_D0) {
compositeImage = compositeImage.rot(compositeAutoRotation);
}
if (compositeAutoFlip) {
compositeImage = compositeImage.flip(VIPS_DIRECTION_VERTICAL);
}
if (compositeAutoFlop) {
compositeImage = compositeImage.flip(VIPS_DIRECTION_HORIZONTAL);
}
}
// Verify within current dimensions
if (compositeImage.width() > image.width() || compositeImage.height() > image.height()) {
throw vips::VError("Image to composite must have same dimensions or smaller");
@@ -1567,7 +1587,6 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight");
baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope");
baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
baton->angle = sharp::AttrAsInt32(options, "angle");
baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");
baton->rotationBackground = sharp::AttrAsVectorOfDouble(options, "rotationBackground");