Merge pull request #83 from julianojulio/master

Add support for maintaining metadata in output image, thanks @julianojulio #83
This commit is contained in:
Lovell Fuller 2014-08-26 08:31:58 +01:00
commit 15160d3b61
5 changed files with 47 additions and 10 deletions

View File

@ -130,12 +130,13 @@ sharp('input.png')
.rotate(180)
.resize(300)
.sharpen()
.withMetadata()
.quality(90)
.webp()
.toBuffer()
.then(function(outputBuffer) {
// 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
#### withMetadata([boolean])
Specifies if the output image should contains the original metadata or not.
#### 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.

View File

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

View File

@ -5,7 +5,8 @@
"contributors": [
"Pierre Inglebert <pierre.inglebert@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",
"scripts": {

View File

@ -33,6 +33,7 @@ struct resize_baton {
int compressionLevel;
int angle;
std::string err;
bool withMetadata;
resize_baton():
buffer_in_len(0),
@ -42,7 +43,8 @@ struct resize_baton {
max(false),
sharpen(false),
progressive(false),
without_enlargement(false) {}
without_enlargement(false),
withMetadata(false) {}
};
typedef enum {
@ -585,37 +587,37 @@ class ResizeWorker : public NanAsyncWorker {
VipsImage *output = cached;
if (baton->output == "__jpeg" || (baton->output == "__input" && inputImageType == JPEG)) {
// 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);
}
} else if (baton->output == "__png" || (baton->output == "__input" && inputImageType == PNG)) {
// 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);
}
} else if (baton->output == "__webp" || (baton->output == "__input" && inputImageType == WEBP)) {
// 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);
}
} else if (is_jpeg(baton->output)) {
// 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);
}
} else if (is_png(baton->output)) {
// 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);
}
} else if (is_webp(baton->output)) {
// 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);
}
} else if (is_tiff(baton->output)) {
// 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);
}
} else {
@ -706,6 +708,7 @@ NAN_METHOD(resize) {
baton->quality = options->Get(NanNew<String>("quality"))->Int32Value();
baton->compressionLevel = options->Get(NanNew<String>("compressionLevel"))->Int32Value();
baton->angle = options->Get(NanNew<String>("angle"))->Int32Value();
baton->withMetadata = options->Get(NanNew<String>("withMetadata"))->BooleanValue();
// Output filename or __format for Buffer
baton->output = *String::Utf8Value(options->Get(NanNew<String>("output"))->ToString());

View File

@ -422,6 +422,28 @@ async.series([
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
function(done) {
sharp(inputJpg).metadata(function(err, metadata) {