mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 05:36:18 +01:00
Compare commits
8 Commits
v0.26.0-al
...
v0.26.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b6d45ab8e | ||
|
|
7980341923 | ||
|
|
3917efdebd | ||
|
|
eaecb7347b | ||
|
|
05ca7d3129 | ||
|
|
4beae0de71 | ||
|
|
b711661784 | ||
|
|
0c4a45b1f4 |
@@ -29,6 +29,7 @@ Implements the [stream.Duplex][1] class.
|
||||
- `options.pages` **[number][6]** number of pages to extract for multi-page input (GIF, TIFF, PDF), use -1 for all pages. (optional, default `1`)
|
||||
- `options.page` **[number][6]** page number to start extracting from for multi-page input (GIF, TIFF, PDF), zero based. (optional, default `0`)
|
||||
- `options.level` **[number][6]** level to extract from a multi-level input (OpenSlide), zero based. (optional, default `0`)
|
||||
- `options.animated` **[boolean][5]** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default `false`)
|
||||
- `options.raw` **[Object][4]?** describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
- `options.raw.width` **[number][6]?**
|
||||
- `options.raw.height` **[number][6]?**
|
||||
@@ -78,6 +79,11 @@ sharp({
|
||||
.then( ... );
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Convert an animated GIF to an animated WebP
|
||||
await sharp('in.gif', { animated: true }).toFile('out.webp');
|
||||
```
|
||||
|
||||
- Throws **[Error][8]** Invalid parameters
|
||||
|
||||
Returns **[Sharp][9]**
|
||||
|
||||
@@ -91,7 +91,8 @@ Returns **[Promise][5]<[Buffer][8]>** when no callback is provided
|
||||
## withMetadata
|
||||
|
||||
Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
|
||||
This will also convert to and add a web-friendly sRGB ICC profile.
|
||||
This will also convert to and add a web-friendly sRGB ICC profile unless a custom
|
||||
output profile is provided.
|
||||
|
||||
The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
|
||||
sRGB colour space and strip all metadata, including the removal of any ICC profile.
|
||||
@@ -100,6 +101,7 @@ sRGB colour space and strip all metadata, including the removal of any ICC profi
|
||||
|
||||
- `options` **[Object][6]?**
|
||||
- `options.orientation` **[number][9]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
|
||||
- `options.icc` **[string][2]?** filesystem path to output ICC profile, defaults to sRGB.
|
||||
|
||||
### Examples
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ Requires libvips v8.10.0
|
||||
[#2259](https://github.com/lovell/sharp/pull/2259)
|
||||
[@vouillon](https://github.com/vouillon)
|
||||
|
||||
* Add support to `withMetadata` for custom ICC profile.
|
||||
[#2271](https://github.com/lovell/sharp/pull/2271)
|
||||
[@roborourke](https://github.com/roborourke)
|
||||
|
||||
* Ensure prebuilt binaries for ARM default to v7 when using Electron.
|
||||
[#2292](https://github.com/lovell/sharp/pull/2292)
|
||||
[@diegodev3](https://github.com/diegodev3)
|
||||
|
||||
@@ -194,3 +194,6 @@ GitHub: https://github.com/vouillon
|
||||
|
||||
Name: Tomáš Szabo
|
||||
GitHub: https://github.com/deftomat
|
||||
|
||||
Name: Robert O'Rourke
|
||||
GitHub: https://github.com/roborourke
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const { execFileSync } = require('child_process');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const { prebuild_upload: hasToken, APPVEYOR_REPO_TAG_NAME, TRAVIS_TAG } = process.env;
|
||||
|
||||
if (hasToken && (APPVEYOR_REPO_TAG_NAME || TRAVIS_TAG)) {
|
||||
execFileSync('prebuild', ['--runtime', 'napi', '--target', '3'], { stdio: 'inherit' });
|
||||
spawnSync('node',
|
||||
['./node_modules/prebuild/bin.js', '--runtime', 'napi', '--target', '3'],
|
||||
{ shell: true, stdio: 'inherit' }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ const debuglog = util.debuglog('sharp');
|
||||
* .toBuffer()
|
||||
* .then( ... );
|
||||
*
|
||||
* @example
|
||||
* // Convert an animated GIF to an animated WebP
|
||||
* await sharp('in.gif', { animated: true }).toFile('out.webp');
|
||||
*
|
||||
* @param {(Buffer|string)} [input] - if present, can be
|
||||
* a Buffer containing JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data, or
|
||||
* a String containing the filesystem path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file.
|
||||
@@ -102,6 +106,7 @@ const debuglog = util.debuglog('sharp');
|
||||
* @param {number} [options.pages=1] - number of pages to extract for multi-page input (GIF, TIFF, PDF), use -1 for all pages.
|
||||
* @param {number} [options.page=0] - page number to start extracting from for multi-page input (GIF, TIFF, PDF), zero based.
|
||||
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
|
||||
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`).
|
||||
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
* @param {number} [options.raw.width]
|
||||
* @param {number} [options.raw.height]
|
||||
@@ -187,6 +192,7 @@ const Sharp = function (input, options) {
|
||||
streamOut: false,
|
||||
withMetadata: false,
|
||||
withMetadataOrientation: -1,
|
||||
withMetadataIcc: '',
|
||||
resolveWithObject: false,
|
||||
// output format
|
||||
jpegQuality: 80,
|
||||
|
||||
@@ -99,6 +99,13 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
}
|
||||
}
|
||||
// Multi-page input (GIF, TIFF, PDF)
|
||||
if (is.defined(inputOptions.animated)) {
|
||||
if (is.bool(inputOptions.animated)) {
|
||||
inputDescriptor.pages = inputOptions.animated ? -1 : 1;
|
||||
} else {
|
||||
throw is.invalidParameterError('animated', 'boolean', inputOptions.animated);
|
||||
}
|
||||
}
|
||||
if (is.defined(inputOptions.pages)) {
|
||||
if (is.integer(inputOptions.pages) && is.inRange(inputOptions.pages, -1, 100000)) {
|
||||
inputDescriptor.pages = inputOptions.pages;
|
||||
|
||||
@@ -119,7 +119,8 @@ function toBuffer (options, callback) {
|
||||
|
||||
/**
|
||||
* Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
|
||||
* This will also convert to and add a web-friendly sRGB ICC profile.
|
||||
* This will also convert to and add a web-friendly sRGB ICC profile unless a custom
|
||||
* output profile is provided.
|
||||
*
|
||||
* The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
|
||||
* sRGB colour space and strip all metadata, including the removal of any ICC profile.
|
||||
@@ -132,6 +133,7 @@ function toBuffer (options, callback) {
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {number} [options.orientation] value between 1 and 8, used to update the EXIF `Orientation` tag.
|
||||
* @param {string} [options.icc] filesystem path to output ICC profile, defaults to sRGB.
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
@@ -145,6 +147,13 @@ function withMetadata (options) {
|
||||
throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation);
|
||||
}
|
||||
}
|
||||
if (is.defined(options.icc)) {
|
||||
if (is.string(options.icc)) {
|
||||
this.options.withMetadataIcc = options.icc;
|
||||
} else {
|
||||
throw is.invalidParameterError('icc', 'string filesystem path to ICC profile', options.icc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -399,6 +408,7 @@ function webp (options) {
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid options
|
||||
*/
|
||||
/* istanbul ignore next */
|
||||
function gif (options) {
|
||||
if (!this.constructor.format.magick.output.buffer) {
|
||||
throw new Error('The gif operation requires libvips to have been installed with support for ImageMagick');
|
||||
|
||||
11
package.json
11
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||
"version": "0.26.0-alpha2",
|
||||
"version": "0.26.0-beta1",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://github.com/lovell/sharp",
|
||||
"contributors": [
|
||||
@@ -68,7 +68,8 @@
|
||||
"Brychan Bennett-Odlum <git@brychan.io>",
|
||||
"Edward Silverton <e.silverton@gmail.com>",
|
||||
"Roman Malieiev <aromaleev@gmail.com>",
|
||||
"Tomas Szabo <tomas.szabo@deftomat.com>"
|
||||
"Tomas Szabo <tomas.szabo@deftomat.com>",
|
||||
"Robert O'Rourke <robert@o-rourke.org>"
|
||||
],
|
||||
"scripts": {
|
||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
||||
@@ -130,15 +131,15 @@
|
||||
"icc": "^2.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^8.1.1",
|
||||
"mock-fs": "^4.12.0",
|
||||
"mock-fs": "^4.13.0",
|
||||
"nyc": "^15.1.0",
|
||||
"prebuild": "^10.0.0",
|
||||
"prebuild": "^10.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"semistandard": "^14.2.3"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"config": {
|
||||
"libvips": "8.10.0-rc4",
|
||||
"libvips": "8.10.0",
|
||||
"runtime": "napi",
|
||||
"target": 3
|
||||
},
|
||||
|
||||
@@ -684,6 +684,15 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply output ICC profile
|
||||
if (!baton->withMetadataIcc.empty()) {
|
||||
image = image.icc_transform(
|
||||
const_cast<char*>(baton->withMetadataIcc.data()),
|
||||
VImage::option()
|
||||
->set("input_profile", "srgb")
|
||||
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
||||
}
|
||||
|
||||
// Override EXIF Orientation tag
|
||||
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
|
||||
image = sharp::SetExifOrientation(image, baton->withMetadataOrientation);
|
||||
@@ -1319,6 +1328,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->fileOut = sharp::AttrAsStr(options, "fileOut");
|
||||
baton->withMetadata = sharp::AttrAsBool(options, "withMetadata");
|
||||
baton->withMetadataOrientation = sharp::AttrAsUint32(options, "withMetadataOrientation");
|
||||
baton->withMetadataIcc = sharp::AttrAsStr(options, "withMetadataIcc");
|
||||
// Format-specific
|
||||
baton->jpegQuality = sharp::AttrAsUint32(options, "jpegQuality");
|
||||
baton->jpegProgressive = sharp::AttrAsBool(options, "jpegProgressive");
|
||||
|
||||
@@ -155,6 +155,7 @@ struct PipelineBaton {
|
||||
std::string err;
|
||||
bool withMetadata;
|
||||
int withMetadataOrientation;
|
||||
std::string withMetadataIcc;
|
||||
std::unique_ptr<double[]> convKernel;
|
||||
int convKernelWidth;
|
||||
int convKernelHeight;
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
"benchmark": "^2.1.4",
|
||||
"gm": "^1.23.1",
|
||||
"imagemagick": "^0.1.3",
|
||||
"jimp": "^0.9.3",
|
||||
"mapnik": "^4.3.1",
|
||||
"jimp": "^0.16.0",
|
||||
"mapnik": "^4.5.2",
|
||||
"semver": "^7.1.1"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8.5.0"
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,8 +564,9 @@ async.series({
|
||||
},
|
||||
// PNG
|
||||
png: function (callback) {
|
||||
const inputPngBuffer = fs.readFileSync(fixtures.inputPng);
|
||||
const inputPngBuffer = fs.readFileSync(fixtures.inputPngAlphaPremultiplicationLarge);
|
||||
const pngSuite = new Benchmark.Suite('png');
|
||||
const minSamples = 64;
|
||||
// jimp
|
||||
pngSuite.add('jimp-buffer-buffer', {
|
||||
defer: true,
|
||||
@@ -576,6 +577,8 @@ async.series({
|
||||
} else {
|
||||
image
|
||||
.resize(width, height)
|
||||
.deflateLevel(6)
|
||||
.filterType(0)
|
||||
.getBuffer(jimp.MIME_PNG, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -589,12 +592,14 @@ async.series({
|
||||
}).add('jimp-file-file', {
|
||||
defer: true,
|
||||
fn: function (deferred) {
|
||||
jimp.read(fixtures.inputPng, function (err, image) {
|
||||
jimp.read(fixtures.inputPngAlphaPremultiplicationLarge, function (err, image) {
|
||||
if (err) {
|
||||
throw err;
|
||||
} else {
|
||||
image
|
||||
.resize(width, height)
|
||||
.deflateLevel(6)
|
||||
.filterType(0)
|
||||
.write(fixtures.outputPng, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -610,7 +615,7 @@ async.series({
|
||||
pngSuite.add('mapnik-file-file', {
|
||||
defer: true,
|
||||
fn: function (deferred) {
|
||||
mapnik.Image.open(fixtures.inputPng, function (err, img) {
|
||||
mapnik.Image.open(fixtures.inputPngAlphaPremultiplicationLarge, function (err, img) {
|
||||
if (err) throw err;
|
||||
img.premultiply(function (err, img) {
|
||||
if (err) throw err;
|
||||
@@ -657,11 +662,15 @@ async.series({
|
||||
defer: true,
|
||||
fn: function (deferred) {
|
||||
imagemagick.resize({
|
||||
srcPath: fixtures.inputPng,
|
||||
srcPath: fixtures.inputPngAlphaPremultiplicationLarge,
|
||||
dstPath: fixtures.outputPng,
|
||||
width: width,
|
||||
height: height,
|
||||
filter: 'Lanczos'
|
||||
filter: 'Lanczos',
|
||||
customArgs: [
|
||||
'-define', 'PNG:compression-level=6',
|
||||
'-define', 'PNG:compression-filter=0'
|
||||
]
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -675,9 +684,11 @@ async.series({
|
||||
pngSuite.add('gm-file-file', {
|
||||
defer: true,
|
||||
fn: function (deferred) {
|
||||
gm(fixtures.inputPng)
|
||||
gm(fixtures.inputPngAlphaPremultiplicationLarge)
|
||||
.filter('Lanczos')
|
||||
.resize(width, height)
|
||||
.define('PNG:compression-level=6')
|
||||
.define('PNG:compression-filter=0')
|
||||
.write(fixtures.outputPng, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -689,9 +700,11 @@ async.series({
|
||||
}).add('gm-file-buffer', {
|
||||
defer: true,
|
||||
fn: function (deferred) {
|
||||
gm(fixtures.inputPng)
|
||||
gm(fixtures.inputPngAlphaPremultiplicationLarge)
|
||||
.filter('Lanczos')
|
||||
.resize(width, height)
|
||||
.define('PNG:compression-level=6')
|
||||
.define('PNG:compression-filter=0')
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -705,9 +718,11 @@ async.series({
|
||||
// sharp
|
||||
pngSuite.add('sharp-buffer-file', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(inputPngBuffer)
|
||||
.resize(width, height)
|
||||
.png({ compressionLevel: 6 })
|
||||
.toFile(fixtures.outputPng, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -718,9 +733,11 @@ async.series({
|
||||
}
|
||||
}).add('sharp-buffer-buffer', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(inputPngBuffer)
|
||||
.resize(width, height)
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -732,9 +749,11 @@ async.series({
|
||||
}
|
||||
}).add('sharp-file-file', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(fixtures.inputPng)
|
||||
sharp(fixtures.inputPngAlphaPremultiplicationLarge)
|
||||
.resize(width, height)
|
||||
.png({ compressionLevel: 6 })
|
||||
.toFile(fixtures.outputPng, function (err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -745,9 +764,11 @@ async.series({
|
||||
}
|
||||
}).add('sharp-file-buffer', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(fixtures.inputPng)
|
||||
sharp(fixtures.inputPngAlphaPremultiplicationLarge)
|
||||
.resize(width, height)
|
||||
.png({ compressionLevel: 6 })
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -759,10 +780,11 @@ async.series({
|
||||
}
|
||||
}).add('sharp-progressive', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(inputPngBuffer)
|
||||
.resize(width, height)
|
||||
.png({ progressive: true })
|
||||
.png({ compressionLevel: 6, progressive: true })
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -774,10 +796,27 @@ async.series({
|
||||
}
|
||||
}).add('sharp-adaptiveFiltering', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(inputPngBuffer)
|
||||
.resize(width, height)
|
||||
.png({ adaptiveFiltering: true })
|
||||
.png({ adaptiveFiltering: true, compressionLevel: 6 })
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
} else {
|
||||
assert.notStrictEqual(null, buffer);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).add('sharp-compressionLevel=9', {
|
||||
defer: true,
|
||||
minSamples,
|
||||
fn: function (deferred) {
|
||||
sharp(inputPngBuffer)
|
||||
.resize(width, height)
|
||||
.png({ compressionLevel: 9 })
|
||||
.toBuffer(function (err, buffer) {
|
||||
if (err) {
|
||||
throw err;
|
||||
|
||||
BIN
test/fixtures/expected/hilutite.jpg
vendored
Normal file
BIN
test/fixtures/expected/hilutite.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
test/fixtures/expected/icc-cmyk.jpg
vendored
Normal file
BIN
test/fixtures/expected/icc-cmyk.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
BIN
test/fixtures/hilutite.icm
vendored
Normal file
BIN
test/fixtures/hilutite.icm
vendored
Normal file
Binary file not shown.
@@ -649,6 +649,15 @@ describe('Input/output', function () {
|
||||
sharp({ density: 'zoinks' });
|
||||
}, /Expected number between 1 and 2400 for density but received zoinks of type string/);
|
||||
});
|
||||
it('Setting animated property updates pages property', function () {
|
||||
assert.strictEqual(sharp({ animated: false }).options.input.pages, 1);
|
||||
assert.strictEqual(sharp({ animated: true }).options.input.pages, -1);
|
||||
});
|
||||
it('Invalid animated property throws', function () {
|
||||
assert.throws(function () {
|
||||
sharp({ animated: -1 });
|
||||
}, /Expected boolean for animated but received -1 of type number/);
|
||||
});
|
||||
it('Invalid page property throws', function () {
|
||||
assert.throws(function () {
|
||||
sharp({ page: -1 });
|
||||
|
||||
@@ -501,6 +501,42 @@ describe('Image metadata', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('Apply CMYK output ICC profile', function (done) {
|
||||
const output = fixtures.path('output.icc-cmyk.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.withMetadata({ icc: 'cmyk' })
|
||||
.toFile(output, function (err, info) {
|
||||
if (err) throw err;
|
||||
sharp(output).metadata(function (err, metadata) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(true, metadata.hasProfile);
|
||||
assert.strictEqual('cmyk', metadata.space);
|
||||
assert.strictEqual(4, metadata.channels);
|
||||
// ICC
|
||||
assert.strictEqual('object', typeof metadata.icc);
|
||||
assert.strictEqual(true, metadata.icc instanceof Buffer);
|
||||
const profile = icc.parse(metadata.icc);
|
||||
assert.strictEqual('object', typeof profile);
|
||||
assert.strictEqual('CMYK', profile.colorSpace);
|
||||
assert.strictEqual('Relative', profile.intent);
|
||||
assert.strictEqual('Printer', profile.deviceClass);
|
||||
});
|
||||
fixtures.assertSimilar(output, fixtures.path('expected/icc-cmyk.jpg'), { threshold: 0 }, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Apply custom output ICC profile', function (done) {
|
||||
const output = fixtures.path('output.hilutite.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.withMetadata({ icc: fixtures.path('hilutite.icm') })
|
||||
.toFile(output, function (err, info) {
|
||||
if (err) throw err;
|
||||
fixtures.assertMaxColourDistance(output, fixtures.path('expected/hilutite.jpg'), 0);
|
||||
fixtures.assertMaxColourDistance(output, fixtures.inputJpg, 16.5);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Include metadata in output, enabled via empty object', () =>
|
||||
sharp(fixtures.inputJpgWithExif)
|
||||
.withMetadata({})
|
||||
@@ -675,5 +711,10 @@ describe('Image metadata', function () {
|
||||
sharp().withMetadata({ orientation: 9 });
|
||||
});
|
||||
});
|
||||
it('Non string icc', function () {
|
||||
assert.throws(function () {
|
||||
sharp().withMetadata({ icc: true });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user