Add usage example and further unit test for new max option

Simplify max vs crop logic
This commit is contained in:
Lovell Fuller 2014-05-19 21:52:47 +01:00
parent ad7735a0a6
commit 276ba5228b
3 changed files with 40 additions and 18 deletions

View File

@ -85,25 +85,25 @@ sharp('input.jpg').resize(300, 200).write('output.jpg', function(err) {
``` ```
```javascript ```javascript
sharp('input.jpg').resize(null, 200).progressive().toBuffer(function(err, buffer) { sharp('input.jpg').resize(null, 200).progressive().toBuffer(function(err, outputBuffer) {
if (err) { if (err) {
throw err; throw err;
} }
// buffer contains progressive JPEG image data, 200 pixels high // outputBuffer contains progressive JPEG image data, 200 pixels high
}); });
``` ```
```javascript ```javascript
sharp('input.png').resize(300).sharpen().quality(90).webp(function(err, buffer) { sharp('input.png').resize(300).sharpen().quality(90).webp(function(err, outputBuffer) {
if (err) { if (err) {
throw err; throw err;
} }
// buffer contains 300 pixels wide, sharpened, 90% quality WebP image data // outputBuffer contains 300 pixels wide, sharpened, 90% quality WebP image data
}); });
``` ```
```javascript ```javascript
sharp(buffer).resize(200, 300).embedWhite().write('output.tiff', function(err) { sharp(inputBuffer).resize(200, 300).embedWhite().write('output.tiff', function(err) {
if (err) { if (err) {
throw err; throw err;
} }
@ -113,15 +113,25 @@ sharp(buffer).resize(200, 300).embedWhite().write('output.tiff', function(err) {
``` ```
```javascript ```javascript
sharp('input.gif').resize(200, 300).embedBlack().webp(function(err, buffer) { sharp('input.gif').resize(200, 300).embedBlack().webp(function(err, outputBuffer) {
if (err) { if (err) {
throw err; throw err;
} }
// buffer contains WebP image data of a 200 pixels wide and 300 pixels high image // outputBuffer contains WebP image data of a 200 pixels wide and 300 pixels high
// containing a scaled version, embedded on a black canvas, of input.gif // containing a scaled version, embedded on a black canvas, of input.gif
}); });
``` ```
```javascript
sharp(inputBuffer).resize(200, 200).max().jpeg(function(err, outputBuffer) {
if (err) {
throw err;
}
// outputBuffer contains JPEG image data no wider than 200 pixels and no higher
// than 200 pixels regardless of the inputBuffer image dimensions
});
```
## API ## API
### sharp(input) ### sharp(input)
@ -147,6 +157,8 @@ Crop the resized image to the exact size specified, the default behaviour.
Preserving aspect ratio, resize the image to the maximum width or height specified. Preserving aspect ratio, resize the image to the maximum width or height specified.
Both `width` and `height` must be provided via `resize` otherwise the behaviour will default to `crop`.
### 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

@ -140,11 +140,11 @@ class ResizeWorker : public NanAsyncWorker {
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 max is set, we need to compute the real size of the thumb image
if(baton->max) { if (baton->max) {
if(xfactor > yfactor) { if (xfactor > yfactor) {
baton->height = round(in->Ysize/factor); baton->height = round(static_cast<double>(in->Ysize) / xfactor);
} else { } else {
baton->width = round(in->Xsize/factor); baton->width = round(static_cast<double>(in->Xsize) / yfactor);
} }
} }
} else if (baton->width > 0) { } else if (baton->width > 0) {
@ -235,8 +235,8 @@ 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 || baton->max) { if (baton->crop) {
// Crop // Crop/max
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);
int left = (affined->Xsize - width + 1) / 2; int left = (affined->Xsize - width + 1) / 2;
@ -355,13 +355,11 @@ NAN_METHOD(resize) {
if (canvas->Equals(NanSymbol("c"))) { if (canvas->Equals(NanSymbol("c"))) {
baton->crop = true; baton->crop = true;
} else if (canvas->Equals(NanSymbol("w"))) { } else if (canvas->Equals(NanSymbol("w"))) {
baton->crop = false;
baton->extend = VIPS_EXTEND_WHITE; baton->extend = VIPS_EXTEND_WHITE;
} else if (canvas->Equals(NanSymbol("b"))) { } else if (canvas->Equals(NanSymbol("b"))) {
baton->crop = false;
baton->extend = VIPS_EXTEND_BLACK; baton->extend = VIPS_EXTEND_BLACK;
} else if (canvas->Equals(NanSymbol("m"))) { } else if (canvas->Equals(NanSymbol("m"))) {
baton->crop = false; baton->crop = true;
baton->max = true; baton->max = true;
} }
baton->sharpen = args[6]->BooleanValue(); baton->sharpen = args[6]->BooleanValue();

View File

@ -112,7 +112,7 @@ async.series([
}, },
// Resize to max width or height considering ratio (landscape) // Resize to max width or height considering ratio (landscape)
function(done) { function(done) {
sharp(inputJpg).resize(320,320).max().write(outputJpg, function(err) { sharp(inputJpg).resize(320, 320).max().write(outputJpg, function(err) {
if (err) throw err; if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) { imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err; if (err) throw err;
@ -124,7 +124,7 @@ async.series([
}, },
// Resize to max width or height considering ratio (portrait) // Resize to max width or height considering ratio (portrait)
function(done) { function(done) {
sharp(inputTiff).resize(320,320).max().write(outputJpg, function(err) { sharp(inputTiff).resize(320, 320).max().write(outputJpg, function(err) {
if (err) throw err; if (err) throw err;
imagemagick.identify(outputJpg, function(err, features) { imagemagick.identify(outputJpg, function(err, features) {
if (err) throw err; if (err) throw err;
@ -133,5 +133,17 @@ async.series([
done(); done();
}); });
}); });
},
// Attempt to resize to max but only provide one dimension, so should default to crop
function(done) {
sharp(inputJpg).resize(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();
});
});
} }
]); ]);