add max option #18

This commit is contained in:
Pierre Inglebert 2014-05-19 20:16:28 +02:00
parent 308d1971d8
commit 88edad3fae
4 changed files with 48 additions and 3 deletions

View File

@ -143,6 +143,10 @@ Scale to `width` x `height`. By default, the resized image is cropped to the exa
Crop the resized image to the exact size specified, the default behaviour. Crop the resized image to the exact size specified, the default behaviour.
### max()
Preserving aspect ratio, resize the image to the maximum width or height specified.
### embedWhite() ### embedWhite()
Embed the resized image on a white background of the exact size specified. Embed the resized image on a white background of the exact size specified.

View File

@ -44,6 +44,12 @@ Sharp.prototype.embedBlack = function() {
return this; return this;
}; };
Sharp.prototype.max = function() {
this.options.canvas = 'm';
return this;
};
Sharp.prototype.sharpen = function(sharpen) { Sharp.prototype.sharpen = function(sharpen) {
this.options.sharpen = (typeof sharpen === 'boolean') ? sharpen : true; this.options.sharpen = (typeof sharpen === 'boolean') ? sharpen : true;
return this; return this;

View File

@ -20,6 +20,7 @@ struct resize_baton {
int width; int width;
int height; int height;
bool crop; bool crop;
bool max;
VipsExtend extend; VipsExtend extend;
bool sharpen; bool sharpen;
bool progressive; bool progressive;
@ -28,7 +29,7 @@ struct resize_baton {
int compressionLevel; int compressionLevel;
std::string err; std::string err;
resize_baton(): buffer_in_len(0), buffer_out_len(0) {} resize_baton(): buffer_in_len(0), buffer_out_len(0), crop(false), max(false), sharpen(false), progressive(false) {}
}; };
typedef enum { typedef enum {
@ -138,6 +139,14 @@ class ResizeWorker : public NanAsyncWorker {
double xfactor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width); double xfactor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width);
double yfactor = static_cast<double>(in->Ysize) / static_cast<double>(baton->height); double yfactor = static_cast<double>(in->Ysize) / static_cast<double>(baton->height);
factor = baton->crop ? std::min(xfactor, yfactor) : std::max(xfactor, yfactor); factor = baton->crop ? std::min(xfactor, yfactor) : std::max(xfactor, yfactor);
// if max is set, we need to compute the real size of the thumb image
if(baton->max) {
if(xfactor > yfactor) {
baton->height = round(in->Ysize/factor);
} else {
baton->width = round(in->Xsize/factor);
}
}
} else if (baton->width > 0) { } else if (baton->width > 0) {
// Fixed width, auto height // Fixed width, auto height
factor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width); factor = static_cast<double>(in->Xsize) / static_cast<double>(baton->width);
@ -226,7 +235,7 @@ class ResizeWorker : public NanAsyncWorker {
// Crop/embed // Crop/embed
VipsImage *canvased = vips_image_new(); VipsImage *canvased = vips_image_new();
if (affined->Xsize != baton->width || affined->Ysize != baton->height) { if (affined->Xsize != baton->width || affined->Ysize != baton->height) {
if (baton->crop) { if (baton->crop || baton->max) {
// Crop // Crop
int width = std::min(affined->Xsize, baton->width); int width = std::min(affined->Xsize, baton->width);
int height = std::min(affined->Ysize, baton->height); int height = std::min(affined->Ysize, baton->height);
@ -351,6 +360,9 @@ NAN_METHOD(resize) {
} else if (canvas->Equals(NanSymbol("b"))) { } else if (canvas->Equals(NanSymbol("b"))) {
baton->crop = false; baton->crop = false;
baton->extend = VIPS_EXTEND_BLACK; baton->extend = VIPS_EXTEND_BLACK;
} else if (canvas->Equals(NanSymbol("m"))) {
baton->crop = false;
baton->max = true;
} }
baton->sharpen = args[6]->BooleanValue(); baton->sharpen = args[6]->BooleanValue();
baton->progressive = args[7]->BooleanValue(); baton->progressive = args[7]->BooleanValue();

View File

@ -109,6 +109,29 @@ async.series([
done(); done();
}); });
}); });
},
// Resize to max width or height considering ratio (landscape)
function(done) {
sharp(inputJpg).resize(320,320).max().write(outputJpg, function(err) {
if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err;
assert.strictEqual(320, features.width);
assert.strictEqual(261, features.height);
done();
});
});
},
// Resize to max width or height considering ratio (portrait)
function(done) {
sharp(inputTiff).resize(320,320).max().write(outputJpg, function(err) {
if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err;
assert.strictEqual(243, features.width);
assert.strictEqual(320, features.height);
done();
});
});
} }
]); ]);