Allow override of EXIF Orientation tag #189

Clear Orientation when rotate/flip/flop are used
This commit is contained in:
Lovell Fuller
2015-07-13 20:00:33 +01:00
parent 642e5687b6
commit d303703dc5
7 changed files with 130 additions and 11 deletions

View File

@@ -25,6 +25,8 @@
#endif
#endif
#define EXIF_IFD0_ORIENTATION "exif-ifd0-Orientation"
namespace sharp {
// How many tasks are in the queue?
@@ -141,14 +143,30 @@ namespace sharp {
int orientation = 0;
const char *exif;
if (
vips_image_get_typeof(image, "exif-ifd0-Orientation") != 0 &&
!vips_image_get_string(image, "exif-ifd0-Orientation", &exif)
vips_image_get_typeof(image, EXIF_IFD0_ORIENTATION) != 0 &&
!vips_image_get_string(image, EXIF_IFD0_ORIENTATION, &exif)
) {
orientation = atoi(&exif[0]);
}
return orientation;
}
/*
Set EXIF Orientation of image.
*/
void SetExifOrientation(VipsImage *image, int const orientation) {
char exif[3];
g_snprintf(exif, sizeof(exif), "%d", orientation);
vips_image_set_string(image, EXIF_IFD0_ORIENTATION, exif);
}
/*
Remove EXIF Orientation from image.
*/
void RemoveExifOrientation(VipsImage *image) {
vips_image_remove(image, EXIF_IFD0_ORIENTATION);
}
/*
Returns the window size for the named interpolator. For example,
a window size of 3 means a 3x3 pixel grid is used for the calculation.

View File

@@ -64,6 +64,16 @@ namespace sharp {
*/
int ExifOrientation(VipsImage const *image);
/*
Set EXIF Orientation of image.
*/
void SetExifOrientation(VipsImage *image, int const orientation);
/*
Remove EXIF Orientation from image.
*/
void RemoveExifOrientation(VipsImage *image);
/*
Returns the window size for the named interpolator. For example,
a window size of 3 means a 3x3 pixel grid is used for the calculation.

View File

@@ -36,6 +36,8 @@ using sharp::InterpolatorWindowSize;
using sharp::HasProfile;
using sharp::HasAlpha;
using sharp::ExifOrientation;
using sharp::SetExifOrientation;
using sharp::RemoveExifOrientation;
using sharp::IsJpeg;
using sharp::IsPng;
using sharp::IsWebp;
@@ -109,6 +111,7 @@ struct PipelineBaton {
bool optimiseScans;
std::string err;
bool withMetadata;
int withMetadataOrientation;
int tileSize;
int tileOverlap;
@@ -142,6 +145,7 @@ struct PipelineBaton {
overshootDeringing(false),
optimiseScans(false),
withMetadata(false),
withMetadataOrientation(-1),
tileSize(256),
tileOverlap(0) {
background[0] = 0.0;
@@ -246,6 +250,7 @@ class PipelineWorker : public NanAsyncWorker {
}
vips_object_local(hook, rotated);
image = rotated;
RemoveExifOrientation(image);
}
// Pre extraction
@@ -563,6 +568,7 @@ class PipelineWorker : public NanAsyncWorker {
}
vips_object_local(hook, rotated);
image = rotated;
RemoveExifOrientation(image);
}
// Flip (mirror about Y axis)
@@ -573,6 +579,7 @@ class PipelineWorker : public NanAsyncWorker {
}
vips_object_local(hook, flipped);
image = flipped;
RemoveExifOrientation(image);
}
// Flop (mirror about X axis)
@@ -583,6 +590,7 @@ class PipelineWorker : public NanAsyncWorker {
}
vips_object_local(hook, flopped);
image = flopped;
RemoveExifOrientation(image);
}
// Crop/embed
@@ -801,6 +809,11 @@ class PipelineWorker : public NanAsyncWorker {
}
}
// Override EXIF Orientation tag
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
SetExifOrientation(image, baton->withMetadataOrientation);
}
#if !(VIPS_MAJOR_VERSION >= 8 || (VIPS_MAJOR_VERSION >= 7 && VIPS_MINOR_VERSION >= 40 && VIPS_MINOR_VERSION >= 5))
// Generate image tile cache when interlace output is required - no longer required as of libvips 7.40.5+
if (baton->progressive) {
@@ -1194,6 +1207,7 @@ NAN_METHOD(pipeline) {
baton->overshootDeringing = options->Get(NanNew<String>("overshootDeringing"))->BooleanValue();
baton->optimiseScans = options->Get(NanNew<String>("optimiseScans"))->BooleanValue();
baton->withMetadata = options->Get(NanNew<String>("withMetadata"))->BooleanValue();
baton->withMetadataOrientation = options->Get(NanNew<String>("withMetadataOrientation"))->Int32Value();
// Output filename or __format for Buffer
baton->output = *String::Utf8Value(options->Get(NanNew<String>("output"))->ToString());
baton->tileSize = options->Get(NanNew<String>("tileSize"))->Int32Value();