mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 13:46:19 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8acb0ed5d0 | ||
|
|
430e04d894 | ||
|
|
012edb4379 | ||
|
|
11ead360a9 | ||
|
|
84a059d7e3 | ||
|
|
b1b070ae5c | ||
|
|
4eb910fec9 | ||
|
|
f0a9d82bf7 | ||
|
|
6d20a1ca81 | ||
|
|
eca2787213 | ||
|
|
8d146accf3 | ||
|
|
b635d015cd | ||
|
|
261a90c8a2 | ||
|
|
4ae22b3425 | ||
|
|
c9aa9c7723 | ||
|
|
5e0b5969da | ||
|
|
ae6d5e69b1 |
@@ -10,7 +10,7 @@ before_install:
|
|||||||
- cd libvips
|
- cd libvips
|
||||||
- git checkout 7.38
|
- git checkout 7.38
|
||||||
- ./bootstrap.sh
|
- ./bootstrap.sh
|
||||||
- ./configure --enable-debug=no --enable-cxx=no --without-orc --without-python
|
- ./configure --enable-debug=no --enable-cxx=yes --without-orc --without-python
|
||||||
- make
|
- make
|
||||||
- sudo make install
|
- sudo make install
|
||||||
- sudo ldconfig
|
- sudo ldconfig
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -53,7 +53,7 @@ Compiling from source is recommended:
|
|||||||
cd libvips
|
cd libvips
|
||||||
git checkout 7.38
|
git checkout 7.38
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
./configure --enable-debug=no --enable-cxx=no --without-python --without-orc
|
./configure --enable-debug=no --enable-cxx=yes --without-python --without-orc
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
@@ -100,8 +100,8 @@ sharp('input.png').rotate(180).resize(300).sharpen().quality(90).webp().then(fun
|
|||||||
```
|
```
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
sharp(inputBuffer).resize(200, 300).embedWhite().toFile('output.tiff').then(function() {
|
sharp(inputBuffer).resize(200, 300).bicubicInterpolation().embedWhite().toFile('output.tiff').then(function() {
|
||||||
// output.tiff is a 200 pixels wide and 300 pixels high image containing a scaled
|
// output.tiff is a 200 pixels wide and 300 pixels high image containing a bicubic scaled
|
||||||
// version, embedded on a white canvas, of the image data in buffer
|
// version, embedded on a white canvas, of the image data in buffer
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -176,6 +176,18 @@ This is equivalent to GraphicsMagick's `>` geometry option: "change the dimensio
|
|||||||
|
|
||||||
Perform a mild sharpen of the resultant image. This typically reduces performance by 30%.
|
Perform a mild sharpen of the resultant image. This typically reduces performance by 30%.
|
||||||
|
|
||||||
|
### bilinearInterpolation()
|
||||||
|
|
||||||
|
Use [bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation) for image resizing, the default (and fastest) interpolation if none is specified.
|
||||||
|
|
||||||
|
### bicubicInterpolation()
|
||||||
|
|
||||||
|
Use [bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) for image resizing. This typically reduces performance by 5%.
|
||||||
|
|
||||||
|
### nohaloInterpolation()
|
||||||
|
|
||||||
|
Use [Nohalo interpolation](http://eprints.soton.ac.uk/268086/) for image resizing. This typically reduces performance by a factor of 2.
|
||||||
|
|
||||||
### 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.
|
||||||
@@ -220,7 +232,7 @@ Write JPEG image data to a Buffer.
|
|||||||
|
|
||||||
A Promises/A+ promise is returned when `callback` is not provided.
|
A Promises/A+ promise is returned when `callback` is not provided.
|
||||||
|
|
||||||
### png(callback)
|
### png([callback])
|
||||||
|
|
||||||
Write PNG image data to a Buffer.
|
Write PNG image data to a Buffer.
|
||||||
|
|
||||||
|
|||||||
12
binding.gyp
12
binding.gyp
@@ -2,16 +2,14 @@
|
|||||||
'targets': [{
|
'targets': [{
|
||||||
'target_name': 'sharp',
|
'target_name': 'sharp',
|
||||||
'sources': ['src/sharp.cc'],
|
'sources': ['src/sharp.cc'],
|
||||||
|
'variables': {
|
||||||
|
'PKG_CONFIG_PATH': '<!(which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR || true):$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig'
|
||||||
|
},
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'<!@(PKG_CONFIG_PATH="/usr/local/Library/ENV/pkgconfig/10.8:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig" pkg-config --libs vips)'
|
'<!(PKG_CONFIG_PATH="<(PKG_CONFIG_PATH)" pkg-config --libs vips)'
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'/usr/local/include/glib-2.0',
|
'<!(PKG_CONFIG_PATH="<(PKG_CONFIG_PATH)" pkg-config --cflags vips glib-2.0)',
|
||||||
'/usr/local/lib/glib-2.0/include',
|
|
||||||
'/usr/include/glib-2.0',
|
|
||||||
'/usr/lib/glib-2.0/include',
|
|
||||||
'/usr/lib/x86_64-linux-gnu/glib-2.0/include',
|
|
||||||
'/usr/lib/i386-linux-gnu/glib-2.0/include',
|
|
||||||
'<!(node -e "require(\'nan\')")'
|
'<!(node -e "require(\'nan\')")'
|
||||||
],
|
],
|
||||||
'cflags': ['-fexceptions', '-pedantic', '-Wall', '-O3'],
|
'cflags': ['-fexceptions', '-pedantic', '-Wall', '-O3'],
|
||||||
|
|||||||
62
index.js
62
index.js
@@ -15,10 +15,11 @@ var Sharp = function(input) {
|
|||||||
angle: 0,
|
angle: 0,
|
||||||
withoutEnlargement: false,
|
withoutEnlargement: false,
|
||||||
sharpen: false,
|
sharpen: false,
|
||||||
|
interpolator: 'bilinear',
|
||||||
progressive: false,
|
progressive: false,
|
||||||
sequentialRead: false,
|
sequentialRead: false,
|
||||||
quality: 80,
|
quality: 80,
|
||||||
compressionLevel: 6,
|
compressionLevel: 6,
|
||||||
output: '__jpeg'
|
output: '__jpeg'
|
||||||
};
|
};
|
||||||
if (typeof input === 'string') {
|
if (typeof input === 'string') {
|
||||||
@@ -27,10 +28,10 @@ var Sharp = function(input) {
|
|||||||
if (input.length > 0) {
|
if (input.length > 0) {
|
||||||
this.options.bufferIn = input;
|
this.options.bufferIn = input;
|
||||||
} else {
|
} else {
|
||||||
throw 'Buffer is empty';
|
throw new Error('Buffer is empty');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw 'Unsupported input ' + typeof input;
|
throw new Error('Unsupported input ' + typeof input);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -66,7 +67,7 @@ Sharp.prototype.rotate = function(angle) {
|
|||||||
} else if (!Number.isNaN(angle) && [0, 90, 180, 270].indexOf(angle) !== -1) {
|
} else if (!Number.isNaN(angle) && [0, 90, 180, 270].indexOf(angle) !== -1) {
|
||||||
this.options.angle = angle;
|
this.options.angle = angle;
|
||||||
} else {
|
} else {
|
||||||
throw 'Unsupport angle (0, 90, 180, 270) ' + angle;
|
throw new Error('Unsupported angle (0, 90, 180, 270) ' + angle);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -86,6 +87,30 @@ Sharp.prototype.sharpen = function(sharpen) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use bilinear interpolation for the affine transformation (fastest, default)
|
||||||
|
*/
|
||||||
|
Sharp.prototype.bilinearInterpolation = function() {
|
||||||
|
this.options.interpolator = 'bilinear';
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use bicubic interpolation for the affine transformation
|
||||||
|
*/
|
||||||
|
Sharp.prototype.bicubicInterpolation = function() {
|
||||||
|
this.options.interpolator = 'bicubic';
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use Nohalo interpolation for the affine transformation
|
||||||
|
*/
|
||||||
|
Sharp.prototype.nohaloInterpolation = function() {
|
||||||
|
this.options.interpolator = 'nohalo';
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
Sharp.prototype.progressive = function(progressive) {
|
Sharp.prototype.progressive = function(progressive) {
|
||||||
this.options.progressive = (typeof progressive === 'boolean') ? progressive : true;
|
this.options.progressive = (typeof progressive === 'boolean') ? progressive : true;
|
||||||
return this;
|
return this;
|
||||||
@@ -100,7 +125,7 @@ Sharp.prototype.quality = function(quality) {
|
|||||||
if (!Number.isNaN(quality) && quality >= 1 && quality <= 100) {
|
if (!Number.isNaN(quality) && quality >= 1 && quality <= 100) {
|
||||||
this.options.quality = quality;
|
this.options.quality = quality;
|
||||||
} else {
|
} else {
|
||||||
throw 'Invalid quality (1 to 100) ' + quality;
|
throw new Error('Invalid quality (1 to 100) ' + quality);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -109,7 +134,7 @@ Sharp.prototype.compressionLevel = function(compressionLevel) {
|
|||||||
if (!Number.isNaN(compressionLevel) && compressionLevel >= -1 && compressionLevel <= 9) {
|
if (!Number.isNaN(compressionLevel) && compressionLevel >= -1 && compressionLevel <= 9) {
|
||||||
this.options.compressionLevel = compressionLevel;
|
this.options.compressionLevel = compressionLevel;
|
||||||
} else {
|
} else {
|
||||||
throw 'Invalid compressionLevel (-1 to 9) ' + compressionLevel;
|
throw new Error('Invalid compressionLevel (-1 to 9) ' + compressionLevel);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -121,7 +146,7 @@ Sharp.prototype.resize = function(width, height) {
|
|||||||
if (!Number.isNaN(width)) {
|
if (!Number.isNaN(width)) {
|
||||||
this.options.width = width;
|
this.options.width = width;
|
||||||
} else {
|
} else {
|
||||||
throw 'Invalid width ' + width;
|
throw new Error('Invalid width ' + width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!height) {
|
if (!height) {
|
||||||
@@ -130,7 +155,7 @@ Sharp.prototype.resize = function(width, height) {
|
|||||||
if (!Number.isNaN(height)) {
|
if (!Number.isNaN(height)) {
|
||||||
this.options.height = height;
|
this.options.height = height;
|
||||||
} else {
|
} else {
|
||||||
throw 'Invalid height ' + height;
|
throw new Error('Invalid height ' + height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -141,10 +166,20 @@ Sharp.prototype.resize = function(width, height) {
|
|||||||
*/
|
*/
|
||||||
Sharp.prototype.toFile = function(output, callback) {
|
Sharp.prototype.toFile = function(output, callback) {
|
||||||
if (!output || output.length === 0) {
|
if (!output || output.length === 0) {
|
||||||
callback('Invalid output');
|
var errOutputInvalid = new Error('Invalid output');
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
callback(errOutputInvalid);
|
||||||
|
} else {
|
||||||
|
return Promise.reject(errOutputInvalid);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.options.fileIn === output) {
|
if (this.options.fileIn === output) {
|
||||||
callback('Cannot use same file for input and output');
|
var errOutputIsInput = new Error('Cannot use same file for input and output');
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
callback(errOutputIsInput);
|
||||||
|
} else {
|
||||||
|
return Promise.reject(errOutputIsInput);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return this._sharp(output, callback);
|
return this._sharp(output, callback);
|
||||||
}
|
}
|
||||||
@@ -153,7 +188,10 @@ Sharp.prototype.toFile = function(output, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Deprecated to make way for future stream support - remove in v0.6.0
|
// Deprecated to make way for future stream support - remove in v0.6.0
|
||||||
Sharp.prototype.write = Sharp.prototype.toFile;
|
Sharp.prototype.write = require('util').deprecate(
|
||||||
|
Sharp.prototype.toFile,
|
||||||
|
'.write() is deprecated and will be removed in v0.6.0. Use .toFile() instead.'
|
||||||
|
);
|
||||||
|
|
||||||
Sharp.prototype.toBuffer = function(callback) {
|
Sharp.prototype.toBuffer = function(callback) {
|
||||||
return this._sharp('__input', callback);
|
return this._sharp('__input', callback);
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"version": "0.5.0",
|
"version": "0.5.1",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Pierre Inglebert <pierre.inglebert@gmail.com>"
|
"Pierre Inglebert <pierre.inglebert@gmail.com>",
|
||||||
|
"Jonathan Ong <jonathanrichardong@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": {
|
||||||
@@ -31,12 +32,12 @@
|
|||||||
"buffer"
|
"buffer"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nan": "^1.1.2",
|
"nan": "^1.2.0",
|
||||||
"bluebird": "^1.2.4"
|
"bluebird": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"imagemagick": "^0.1.3",
|
"imagemagick": "^0.1.3",
|
||||||
"imagemagick-native": "^1.0.0",
|
"imagemagick-native": "^1.1.1",
|
||||||
"gm": "^1.16.0",
|
"gm": "^1.16.0",
|
||||||
"async": "^0.9.0",
|
"async": "^0.9.0",
|
||||||
"benchmark": "^1.0.0"
|
"benchmark": "^1.0.0"
|
||||||
|
|||||||
46
src/sharp.cc
46
src/sharp.cc
@@ -23,6 +23,7 @@ struct resize_baton {
|
|||||||
bool max;
|
bool max;
|
||||||
VipsExtend extend;
|
VipsExtend extend;
|
||||||
bool sharpen;
|
bool sharpen;
|
||||||
|
std::string interpolator;
|
||||||
bool progressive;
|
bool progressive;
|
||||||
bool without_enlargement;
|
bool without_enlargement;
|
||||||
VipsAccess access_method;
|
VipsAccess access_method;
|
||||||
@@ -294,12 +295,17 @@ class ResizeWorker : public NanAsyncWorker {
|
|||||||
}
|
}
|
||||||
g_object_unref(shrunk_on_load);
|
g_object_unref(shrunk_on_load);
|
||||||
|
|
||||||
// Use vips_affine with the remaining float part using bilinear interpolation
|
// Use vips_affine with the remaining float part
|
||||||
VipsImage *affined = vips_image_new();
|
VipsImage *affined = vips_image_new();
|
||||||
if (residual != 0) {
|
if (residual != 0) {
|
||||||
if (vips_affine(shrunk, &affined, residual, 0, 0, residual, "interpolate", vips_interpolate_bilinear_static(), NULL)) {
|
// Create interpolator - "bilinear" (default), "bicubic" or "nohalo"
|
||||||
|
VipsInterpolate *interpolator = vips_interpolate_new(baton->interpolator.c_str());
|
||||||
|
// Perform affine transformation
|
||||||
|
if (vips_affine(shrunk, &affined, residual, 0, 0, residual, "interpolate", interpolator, NULL)) {
|
||||||
|
g_object_unref(interpolator);
|
||||||
return resize_error(baton, shrunk);
|
return resize_error(baton, shrunk);
|
||||||
}
|
}
|
||||||
|
g_object_unref(interpolator);
|
||||||
} else {
|
} else {
|
||||||
vips_copy(shrunk, &affined, NULL);
|
vips_copy(shrunk, &affined, NULL);
|
||||||
}
|
}
|
||||||
@@ -359,46 +365,51 @@ class ResizeWorker : public NanAsyncWorker {
|
|||||||
}
|
}
|
||||||
g_object_unref(canvased);
|
g_object_unref(canvased);
|
||||||
|
|
||||||
|
// Always convert to sRGB colour space
|
||||||
|
VipsImage *colourspaced = vips_image_new();
|
||||||
|
vips_colourspace(sharpened, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL);
|
||||||
|
g_object_unref(sharpened);
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
if (baton->file_out == "__jpeg" || (baton->file_out == "__input" && inputImageType == JPEG)) {
|
if (baton->file_out == "__jpeg" || (baton->file_out == "__input" && inputImageType == JPEG)) {
|
||||||
// Write JPEG to buffer
|
// Write JPEG to buffer
|
||||||
if (vips_jpegsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
|
if (vips_jpegsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (baton->file_out == "__png" || (baton->file_out == "__input" && inputImageType == PNG)) {
|
} else if (baton->file_out == "__png" || (baton->file_out == "__input" && inputImageType == PNG)) {
|
||||||
// Write PNG to buffer
|
// Write PNG to buffer
|
||||||
if (vips_pngsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
|
if (vips_pngsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (baton->file_out == "__webp" || (baton->file_out == "__input" && inputImageType == WEBP)) {
|
} else if (baton->file_out == "__webp" || (baton->file_out == "__input" && inputImageType == WEBP)) {
|
||||||
// Write WEBP to buffer
|
// Write WEBP to buffer
|
||||||
if (vips_webpsave_buffer(sharpened, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) {
|
if (vips_webpsave_buffer(colourspaced, &baton->buffer_out, &baton->buffer_out_len, "strip", TRUE, "Q", baton->quality, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (is_jpeg(baton->file_out)) {
|
} else if (is_jpeg(baton->file_out)) {
|
||||||
// Write JPEG to file
|
// Write JPEG to file
|
||||||
if (vips_jpegsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
|
if (vips_jpegsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, "optimize_coding", TRUE, "interlace", baton->progressive, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (is_png(baton->file_out)) {
|
} else if (is_png(baton->file_out)) {
|
||||||
// Write PNG to file
|
// Write PNG to file
|
||||||
if (vips_pngsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
|
if (vips_pngsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "compression", baton->compressionLevel, "interlace", baton->progressive, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (is_webp(baton->file_out)) {
|
} else if (is_webp(baton->file_out)) {
|
||||||
// Write WEBP to file
|
// Write WEBP to file
|
||||||
if (vips_webpsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) {
|
if (vips_webpsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "Q", baton->quality, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else if (is_tiff(baton->file_out)) {
|
} else if (is_tiff(baton->file_out)) {
|
||||||
// Write TIFF to file
|
// Write TIFF to file
|
||||||
if (vips_tiffsave(sharpened, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) {
|
if (vips_tiffsave(colourspaced, baton->file_out.c_str(), "strip", TRUE, "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, "Q", baton->quality, NULL)) {
|
||||||
return resize_error(baton, sharpened);
|
return resize_error(baton, colourspaced);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(baton->err).append("Unsupported output " + baton->file_out);
|
(baton->err).append("Unsupported output " + baton->file_out);
|
||||||
}
|
}
|
||||||
g_object_unref(sharpened);
|
g_object_unref(colourspaced);
|
||||||
vips_thread_shutdown();
|
vips_thread_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +467,7 @@ NAN_METHOD(resize) {
|
|||||||
}
|
}
|
||||||
// Other options
|
// Other options
|
||||||
baton->sharpen = options->Get(NanNew<String>("sharpen"))->BooleanValue();
|
baton->sharpen = options->Get(NanNew<String>("sharpen"))->BooleanValue();
|
||||||
|
baton->interpolator = *String::Utf8Value(options->Get(NanNew<String>("interpolator"))->ToString());
|
||||||
baton->progressive = options->Get(NanNew<String>("progressive"))->BooleanValue();
|
baton->progressive = options->Get(NanNew<String>("progressive"))->BooleanValue();
|
||||||
baton->without_enlargement = options->Get(NanNew<String>("withoutEnlargement"))->BooleanValue();
|
baton->without_enlargement = options->Get(NanNew<String>("withoutEnlargement"))->BooleanValue();
|
||||||
baton->access_method = options->Get(NanNew<String>("sequentialRead"))->BooleanValue() ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
|
baton->access_method = options->Get(NanNew<String>("sequentialRead"))->BooleanValue() ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
|
||||||
|
|||||||
@@ -154,6 +154,14 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).add("sharp-file-buffer-promise", {
|
||||||
|
defer: true,
|
||||||
|
fn: function(deferred) {
|
||||||
|
sharp(inputJpg).resize(width, height).toBuffer().then(function(buffer) {
|
||||||
|
assert.notStrictEqual(null, buffer);
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
}).add("sharp-file-buffer-sharpen", {
|
}).add("sharp-file-buffer-sharpen", {
|
||||||
defer: true,
|
defer: true,
|
||||||
fn: function(deferred) {
|
fn: function(deferred) {
|
||||||
@@ -166,6 +174,30 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).add("sharp-file-buffer-bicubic", {
|
||||||
|
defer: true,
|
||||||
|
fn: function(deferred) {
|
||||||
|
sharp(inputJpg).resize(width, height).bicubicInterpolation().toBuffer(function(err, buffer) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
assert.notStrictEqual(null, buffer);
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).add("sharp-file-buffer-nohalo", {
|
||||||
|
defer: true,
|
||||||
|
fn: function(deferred) {
|
||||||
|
sharp(inputJpg).resize(width, height).nohaloInterpolation().toBuffer(function(err, buffer) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
assert.notStrictEqual(null, buffer);
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}).add("sharp-file-buffer-progressive", {
|
}).add("sharp-file-buffer-progressive", {
|
||||||
defer: true,
|
defer: true,
|
||||||
fn: function(deferred) {
|
fn: function(deferred) {
|
||||||
@@ -330,18 +362,6 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).add("sharp-file-buffer-sequentialRead", {
|
|
||||||
defer: true,
|
|
||||||
fn: function(deferred) {
|
|
||||||
sharp(inputPng).sequentialRead().resize(width, height).toBuffer(function(err, buffer) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
} else {
|
|
||||||
assert.notStrictEqual(null, buffer);
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).on("cycle", function(event) {
|
}).on("cycle", function(event) {
|
||||||
console.log(" png " + String(event.target));
|
console.log(" png " + String(event.target));
|
||||||
}).on("complete", function() {
|
}).on("complete", function() {
|
||||||
@@ -408,18 +428,6 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).add("sharp-file-buffer-sequentialRead", {
|
|
||||||
defer: true,
|
|
||||||
fn: function(deferred) {
|
|
||||||
sharp(inputWebp).sequentialRead().resize(width, height).toBuffer(function(err, buffer) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
} else {
|
|
||||||
assert.notStrictEqual(null, buffer);
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).on("cycle", function(event) {
|
}).on("cycle", function(event) {
|
||||||
console.log("webp " + String(event.target));
|
console.log("webp " + String(event.target));
|
||||||
}).on("complete", function() {
|
}).on("complete", function() {
|
||||||
@@ -449,17 +457,6 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).add("sharp-file-file-sequentialRead", {
|
|
||||||
defer: true,
|
|
||||||
fn: function(deferred) {
|
|
||||||
sharp(inputTiff).sequentialRead().resize(width, height).toFile(outputTiff, function(err) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
} else {
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).on("cycle", function(event) {
|
}).on("cycle", function(event) {
|
||||||
console.log("tiff " + String(event.target));
|
console.log("tiff " + String(event.target));
|
||||||
}).on("complete", function() {
|
}).on("complete", function() {
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ async.series([
|
|||||||
},
|
},
|
||||||
// Do not enlarge the output if the input width is already less than the output width
|
// Do not enlarge the output if the input width is already less than the output width
|
||||||
function(done) {
|
function(done) {
|
||||||
sharp(inputJpg).resize(2800).withoutEnlargement().write(outputJpg, function(err) {
|
sharp(inputJpg).resize(2800).withoutEnlargement().toFile(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;
|
||||||
@@ -231,7 +231,7 @@ async.series([
|
|||||||
},
|
},
|
||||||
// Do not enlarge the output if the input height is already less than the output height
|
// Do not enlarge the output if the input height is already less than the output height
|
||||||
function(done) {
|
function(done) {
|
||||||
sharp(inputJpg).resize(null, 2300).withoutEnlargement().write(outputJpg, function(err) {
|
sharp(inputJpg).resize(null, 2300).withoutEnlargement().toFile(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;
|
||||||
@@ -262,5 +262,47 @@ async.series([
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
assert(!fail);
|
assert(!fail);
|
||||||
done();
|
done();
|
||||||
}
|
},
|
||||||
|
// Check colour space conversion occurs from TIFF to WebP (this used to segfault)
|
||||||
|
function(done) {
|
||||||
|
sharp(inputTiff).webp().then(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Interpolation: bilinear
|
||||||
|
function(done) {
|
||||||
|
sharp(inputJpg).resize(320, 240).bilinearInterpolation().toFile(outputJpg, function(err) {
|
||||||
|
if (err) throw err;
|
||||||
|
imagemagick.identify(outputJpg, function(err, features) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(320, features.width);
|
||||||
|
assert.strictEqual(240, features.height);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Interpolation: bicubic
|
||||||
|
function(done) {
|
||||||
|
sharp(inputJpg).resize(320, 240).bicubicInterpolation().toFile(outputJpg, function(err) {
|
||||||
|
if (err) throw err;
|
||||||
|
imagemagick.identify(outputJpg, function(err, features) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(320, features.width);
|
||||||
|
assert.strictEqual(240, features.height);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Interpolation: nohalo
|
||||||
|
function(done) {
|
||||||
|
sharp(inputJpg).resize(320, 240).nohaloInterpolation().toFile(outputJpg, function(err) {
|
||||||
|
if (err) throw err;
|
||||||
|
imagemagick.identify(outputJpg, function(err, features) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(320, features.width);
|
||||||
|
assert.strictEqual(240, features.height);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user