New withMetadata([boolean]) to keep metadata in the generated images.

This commit is contained in:
Juliano Julio Costa 2014-08-22 13:53:42 -04:00
parent b877751b2d
commit c5efb77bad
5 changed files with 47 additions and 10 deletions

View File

@ -130,12 +130,13 @@ sharp('input.png')
.rotate(180) .rotate(180)
.resize(300) .resize(300)
.sharpen() .sharpen()
.withMetadata()
.quality(90) .quality(90)
.webp() .webp()
.toBuffer() .toBuffer()
.then(function(outputBuffer) { .then(function(outputBuffer) {
// outputBuffer contains 300px wide, upside down, sharpened, // outputBuffer contains 300px wide, upside down, sharpened,
// 90% quality WebP image data // with metadata, 90% quality WebP image data
}); });
``` ```
@ -278,6 +279,10 @@ Possible interpolators, in order of performance, are:
### Output options ### Output options
#### withMetadata([boolean])
Specifies if the output image should contains the original metadata or not.
#### progressive() #### progressive()
Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed. Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed.

View File

@ -26,6 +26,7 @@ var Sharp = function(input) {
compressionLevel: 6, compressionLevel: 6,
streamIn: false, streamIn: false,
streamOut: false, streamOut: false,
withMetadata: false,
output: '__input' output: '__input'
}; };
if (typeof input === 'string') { if (typeof input === 'string') {
@ -190,6 +191,11 @@ Sharp.prototype.compressionLevel = function(compressionLevel) {
return this; return this;
}; };
Sharp.prototype.withMetadata = function(withMetadata) {
this.options.withMetadata = (typeof withMetadata === 'boolean') ? withMetadata : true;
return this;
};
Sharp.prototype.resize = function(width, height) { Sharp.prototype.resize = function(width, height) {
if (!width) { if (!width) {
this.options.width = -1; this.options.width = -1;

View File

@ -5,7 +5,8 @@
"contributors": [ "contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>", "Pierre Inglebert <pierre.inglebert@gmail.com>",
"Jonathan Ong <jonathanrichardong@gmail.com>", "Jonathan Ong <jonathanrichardong@gmail.com>",
"Chanon Sajjamanochai <chanon.s@gmail.com>" "Chanon Sajjamanochai <chanon.s@gmail.com>",
"Juliano Julio <julianojulio@gmail.com>"
], ],
"description": "High performance Node.js module to resize JPEG, PNG and WebP images using the libvips library", "description": "High performance Node.js module to resize JPEG, PNG and WebP images using the libvips library",
"scripts": { "scripts": {

View File

@ -33,6 +33,7 @@ struct resize_baton {
int compressionLevel; int compressionLevel;
int angle; int angle;
std::string err; std::string err;
bool withMetadata;
resize_baton(): resize_baton():
buffer_in_len(0), buffer_in_len(0),
@ -42,7 +43,8 @@ struct resize_baton {
max(false), max(false),
sharpen(false), sharpen(false),
progressive(false), progressive(false),
without_enlargement(false) {} without_enlargement(false),
withMetadata(false) {}
}; };
typedef enum { typedef enum {
@ -585,37 +587,37 @@ class ResizeWorker : public NanAsyncWorker {
VipsImage *output = cached; VipsImage *output = cached;
if (baton->output == "__jpeg" || (baton->output == "__input" && inputImageType == JPEG)) { if (baton->output == "__jpeg" || (baton->output == "__input" && inputImageType == JPEG)) {
// Write JPEG to buffer // Write JPEG to buffer
if (vips_jpegsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { if (vips_jpegsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (baton->output == "__png" || (baton->output == "__input" && inputImageType == PNG)) { } else if (baton->output == "__png" || (baton->output == "__input" && inputImageType == PNG)) {
// Write PNG to buffer // Write PNG to buffer
if (vips_pngsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { if (vips_pngsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (baton->output == "__webp" || (baton->output == "__input" && inputImageType == WEBP)) { } else if (baton->output == "__webp" || (baton->output == "__input" && inputImageType == WEBP)) {
// Write WEBP to buffer // Write WEBP to buffer
if (vips_webpsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) { if (vips_webpsave_buffer(output, &baton->buffer_out, &baton->buffer_out_len, "strip", !baton->withMetadata, "Q", baton->quality, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (is_jpeg(baton->output)) { } else if (is_jpeg(baton->output)) {
// Write JPEG to file // Write JPEG to file
if (vips_jpegsave(output, baton->output.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) { if (vips_jpegsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (is_png(baton->output)) { } else if (is_png(baton->output)) {
// Write PNG to file // Write PNG to file
if (vips_pngsave(output, baton->output.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) { if (vips_pngsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (is_webp(baton->output)) { } else if (is_webp(baton->output)) {
// Write WEBP to file // Write WEBP to file
if (vips_webpsave(output, baton->output.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) { if (vips_webpsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "Q", baton->quality, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else if (is_tiff(baton->output)) { } else if (is_tiff(baton->output)) {
// Write TIFF to file // Write TIFF to file
if (vips_tiffsave(output, baton->output.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) { if (vips_tiffsave(output, baton->output.c_str(), "strip", !baton->withMetadata, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) {
return resize_error(baton, output); return resize_error(baton, output);
} }
} else { } else {
@ -706,6 +708,7 @@ NAN_METHOD(resize) {
baton->quality = options->Get(NanNew<String>("quality"))->Int32Value(); baton->quality = options->Get(NanNew<String>("quality"))->Int32Value();
baton->compressionLevel = options->Get(NanNew<String>("compressionLevel"))->Int32Value(); baton->compressionLevel = options->Get(NanNew<String>("compressionLevel"))->Int32Value();
baton->angle = options->Get(NanNew<String>("angle"))->Int32Value(); baton->angle = options->Get(NanNew<String>("angle"))->Int32Value();
baton->withMetadata = options->Get(NanNew<String>("withMetadata"))->BooleanValue();
// Output filename or __format for Buffer // Output filename or __format for Buffer
baton->output = *String::Utf8Value(options->Get(NanNew<String>("output"))->ToString()); baton->output = *String::Utf8Value(options->Get(NanNew<String>("output"))->ToString());

View File

@ -422,6 +422,28 @@ async.series([
done(); done();
}); });
}, },
// Keeps Metadata after a resize
function(done) {
sharp(inputJpgWithExif).resize(320, 240).withMetadata().toBuffer(function(err, buffer) {
if (err) throw err;
sharp(buffer).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual(8, metadata.orientation);
done();
});
});
},
// Keeps Metadata after a resize
function(done) {
sharp(inputJpgWithExif).resize(320, 240).withMetadata(false).toBuffer(function(err, buffer) {
if (err) throw err;
sharp(buffer).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('undefined', typeof metadata.orientation);
done();
});
});
},
// Metadata - JPEG // Metadata - JPEG
function(done) { function(done) {
sharp(inputJpg).metadata(function(err, metadata) { sharp(inputJpg).metadata(function(err, metadata) {