Add autoOrient to composite options

This commit is contained in:
Don Denton 2024-07-13 17:02:06 -04:00
parent 6261f412ff
commit 378885a985
5 changed files with 36 additions and 1 deletions

View File

@ -110,6 +110,7 @@ const blend = {
* @param {number} [images[].input.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
* @param {boolean} [images[].input.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for Pango markup features like `<span foreground="red">Red!</span>`.
* @param {number} [images[].input.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
* @param {Boolean} [images[].autoOrient=false] - set to true to use EXIF orientation data, if present, to orient the image.
* @param {String} [images[].blend='over'] - how to blend this image with the image below.
* @param {String} [images[].gravity='centre'] - gravity at which to place the overlay.
* @param {Number} [images[].top] - the pixel offset from the top edge.
@ -136,8 +137,11 @@ function composite (images) {
throw is.invalidParameterError('image to composite', 'object', image);
}
const inputOptions = this._inputOptionsFromObject(image);
const descriptor = this._createInputDescriptor(image.input, inputOptions, { allowStream: false });
console.log('inputOptions', inputOptions);
console.log('descriptor', descriptor);
const composite = {
input: this._createInputDescriptor(image.input, inputOptions, { allowStream: false }),
input: descriptor,
blend: 'over',
tile: false,
left: 0,

View File

@ -36,6 +36,7 @@ function _inputOptionsFromObject (obj) {
*/
function _createInputDescriptor (input, inputOptions, containerOptions) {
const inputDescriptor = {
autoOrient: false,
failOn: 'warning',
limitInputPixels: Math.pow(0x3FFF, 2),
ignoreIcc: false,

View File

@ -166,6 +166,8 @@ namespace sharp {
descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
// Remove safety features and allow unlimited input
descriptor->unlimited = AttrAsBool(input, "unlimited");
// Use the EXIF orientation to auto orient the image
descriptor->autoOrient = AttrAsBool(input, "autoOrient");
return descriptor;
}

View File

@ -33,6 +33,7 @@ namespace sharp {
struct InputDescriptor { // NOLINT(runtime/indentation_namespace)
std::string name;
std::string file;
bool autoOrient;
char *buffer;
VipsFailOn failOn;
uint64_t limitInputPixels;
@ -73,6 +74,7 @@ namespace sharp {
std::vector<double> pdfBackground;
InputDescriptor():
autoOrient(false),
buffer(nullptr),
failOn(VIPS_FAIL_ON_WARNING),
limitInputPixels(0x3FFF * 0x3FFF),

View File

@ -627,6 +627,32 @@ 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) {
// Calculate angle of rotation
VipsAngle compositeAutoRotation = VIPS_ANGLE_D0;
bool compositeAutoFlip = false;
bool compositeAutoFlop = false;
// Rotate and flip image according to Exif orientation
std::tie(compositeAutoRotation, compositeAutoFlip, compositeAutoFlop) =
CalculateExifRotationAndFlip(sharp::ExifOrientation(compositeImage));
compositeImage = sharp::RemoveExifOrientation(compositeImage);
if (compositeAutoRotation != VIPS_ANGLE_D0) {
compositeImage = compositeImage.rot(compositeAutoRotation);
}
// Mirror vertically (up-down) about the x-axis
if (compositeAutoFlip) {
compositeImage = compositeImage.flip(VIPS_DIRECTION_VERTICAL);
}
// Mirror horizontally (left-right) about the y-axis
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");