Upgrade to libvips v8.8.0, remove deprecated overlayWith
1
.gitignore
vendored
@ -12,4 +12,5 @@ vendor
|
||||
.gitattributes
|
||||
.DS_Store
|
||||
.nyc_output
|
||||
.vscode/
|
||||
package-lock.json
|
||||
|
@ -13,3 +13,4 @@ vendor
|
||||
.prebuildrc
|
||||
.nyc_output
|
||||
.github/
|
||||
.vscode/
|
||||
|
32
.travis.yml
@ -1,11 +1,5 @@
|
||||
matrix:
|
||||
include:
|
||||
- name: "Linux (glibc) - Node 6"
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js: "6"
|
||||
- name: "Linux (glibc) - Node 8"
|
||||
os: linux
|
||||
dist: trusty
|
||||
@ -27,12 +21,6 @@ matrix:
|
||||
after_success:
|
||||
- npm install coveralls
|
||||
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
||||
- name: "Linux (glibc) - Node 11"
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js: "11"
|
||||
- name: "Linux (musl) - Node 8"
|
||||
os: linux
|
||||
dist: trusty
|
||||
@ -53,16 +41,6 @@ matrix:
|
||||
- sudo docker exec sharp apk add build-base git python2 --update-cache
|
||||
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
- name: "Linux (musl) - Node 11"
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: true
|
||||
language: minimal
|
||||
before_install:
|
||||
- sudo docker run -dit --name sharp --env CI --env PREBUILD_TOKEN --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:11-alpine
|
||||
- sudo docker exec sharp apk add build-base git python2 --update-cache
|
||||
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
- name: "Linux (musl) - Node 12"
|
||||
os: linux
|
||||
dist: trusty
|
||||
@ -73,11 +51,6 @@ matrix:
|
||||
- sudo docker exec sharp apk add build-base git python2 --update-cache
|
||||
install: sudo docker exec sharp sh -c "npm install --unsafe-perm"
|
||||
script: sudo docker exec sharp sh -c "npm test"
|
||||
- name: "OS X - Node 6"
|
||||
os: osx
|
||||
osx_image: xcode9.2
|
||||
language: node_js
|
||||
node_js: "6"
|
||||
- name: "OS X - Node 8"
|
||||
os: osx
|
||||
osx_image: xcode9.2
|
||||
@ -88,11 +61,6 @@ matrix:
|
||||
osx_image: xcode9.2
|
||||
language: node_js
|
||||
node_js: "10"
|
||||
- name: "OS X - Node 11"
|
||||
os: osx
|
||||
osx_image: xcode9.2
|
||||
language: node_js
|
||||
node_js: "11"
|
||||
- name: "OS X - Node 12"
|
||||
os: osx
|
||||
osx_image: xcode9.2
|
||||
|
@ -20,7 +20,7 @@ As well as image resizing, operations such as
|
||||
rotation, extraction, compositing and gamma correction are available.
|
||||
|
||||
Most modern 64-bit OS X, Windows and Linux systems running
|
||||
Node versions 6, 8, 10, 11 and 12
|
||||
Node versions 8, 10 and 12
|
||||
do not require any additional install or runtime dependencies.
|
||||
|
||||
## Examples
|
||||
|
@ -4,10 +4,8 @@ build: off
|
||||
platform: x64
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
- nodejs_version: "10"
|
||||
- nodejs_version: "11"
|
||||
- nodejs_version: "12"
|
||||
install:
|
||||
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) x64
|
||||
|
14
binding.gyp
@ -97,7 +97,8 @@
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'defines': [
|
||||
'_ALLOW_KEYWORD_MACROS'
|
||||
'_ALLOW_KEYWORD_MACROS',
|
||||
'_FILE_OFFSET_BITS=64'
|
||||
],
|
||||
'libraries': [
|
||||
'../vendor/lib/libvips.lib',
|
||||
@ -183,22 +184,15 @@
|
||||
'configurations': {
|
||||
'Release': {
|
||||
'cflags_cc': [
|
||||
'-Wno-cast-function-type',
|
||||
'-Wno-deprecated-declarations'
|
||||
'-Wno-cast-function-type'
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [
|
||||
'-Wno-deprecated-declarations'
|
||||
]
|
||||
},
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'ExceptionHandling': 1
|
||||
}
|
||||
},
|
||||
'msvs_disabled_warnings': [
|
||||
4275,
|
||||
4996
|
||||
4275
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
### v0.23 - "*vision*"
|
||||
|
||||
Requires libvips v8.8.0.
|
||||
|
||||
#### v0.23.0 - TBD
|
||||
|
||||
* Remove `overlayWith` previously deprecated in v0.22.0.
|
||||
|
||||
* Drop support for Node.js versions 6 and 11.
|
||||
[#1212](https://github.com/lovell/sharp/issues/1674)
|
||||
|
||||
### v0.22 - "*uptake*"
|
||||
|
||||
Requires libvips v8.7.4.
|
||||
|
@ -16,7 +16,7 @@ As well as image resizing, operations such as
|
||||
rotation, extraction, compositing and gamma correction are available.
|
||||
|
||||
Most modern 64-bit OS X, Windows and Linux systems running
|
||||
Node versions 6, 8, 10, 11 and 12
|
||||
Node versions 8, 10 and 12
|
||||
do not require any additional install or runtime dependencies.
|
||||
|
||||
[](https://coveralls.io/r/lovell/sharp?branch=master)
|
||||
|
@ -10,12 +10,12 @@ yarn add sharp
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Node.js v6+
|
||||
* Node.js v8.5.0+
|
||||
|
||||
### Building from source
|
||||
|
||||
Pre-compiled binaries for sharp are provided for use with
|
||||
Node versions 6, 8, 10, 11 and 12 on
|
||||
Node versions 8, 10 and 12 on
|
||||
64-bit Windows, OS X and Linux platforms.
|
||||
|
||||
Sharp will be built from source at install time when:
|
||||
@ -36,19 +36,20 @@ Building from source requires:
|
||||
[](https://travis-ci.org/lovell/sharp)
|
||||
|
||||
libvips and its dependencies are fetched and stored within `node_modules/sharp/vendor` during `npm install`.
|
||||
This involves an automated HTTPS download of approximately 9MB.
|
||||
This involves an automated HTTPS download of approximately 10MB.
|
||||
|
||||
Most Linux-based (glibc, musl) operating systems running on x64 and ARMv6+ CPUs should "just work", e.g.:
|
||||
|
||||
* Debian 7+
|
||||
* Debian 8+
|
||||
* Ubuntu 14.04+
|
||||
* Centos 7+
|
||||
* Alpine 3.8+ (Node 8+)
|
||||
* Red Hat Enterprise 8
|
||||
* CentOS 8
|
||||
* Alpine 3.8+
|
||||
* Fedora
|
||||
* openSUSE 13.2+
|
||||
* Archlinux
|
||||
* Raspbian Jessie
|
||||
* Amazon Linux
|
||||
* Amazon Linux 2
|
||||
* Solus
|
||||
|
||||
To use a globally-installed version of libvips instead of the provided binaries,
|
||||
@ -61,7 +62,8 @@ and `LD_LIBRARY_PATH` at runtime.
|
||||
|
||||
This allows the use of newer versions of libvips with older versions of sharp.
|
||||
|
||||
For 32-bit Intel CPUs and older Linux-based operating systems such as Centos 6,
|
||||
For 32-bit Intel CPUs and older Linux-based operating systems such as
|
||||
those based on Red Hat Enterprise Linux 7 (e.g. CentOS 7, Amazon Linux 1)
|
||||
compiling libvips from source is recommended.
|
||||
|
||||
[https://libvips.github.io/libvips/install.html#building-libvips-from-a-source-tarball](https://libvips.github.io/libvips/install.html#building-libvips-from-a-source-tarball)
|
||||
@ -97,7 +99,7 @@ that it can be located using `pkg-config --modversion vips-cpp`.
|
||||
[](https://ci.appveyor.com/project/lovell/sharp)
|
||||
|
||||
libvips and its dependencies are fetched and stored within `node_modules\sharp\vendor` during `npm install`.
|
||||
This involves an automated HTTPS download of approximately 14MB.
|
||||
This involves an automated HTTPS download of approximately 10MB.
|
||||
If you are having issues during installation consider removing the directory
|
||||
`C:\Users\[user]\AppData\Roaming\npm-cache\_libvips`.
|
||||
|
||||
@ -150,7 +152,7 @@ docker pull tailor/docker-libvips
|
||||
|
||||
### AWS Lambda
|
||||
|
||||
Set the Lambda runtime to Node.js 8.10.
|
||||
Set the Lambda runtime to `nodejs10.x`.
|
||||
|
||||
The binaries in the `node_modules` directory of the
|
||||
[deployment package](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html)
|
||||
@ -160,14 +162,14 @@ On non-Linux machines such as OS X and Windows run the following:
|
||||
|
||||
```sh
|
||||
rm -rf node_modules/sharp
|
||||
npm install --arch=x64 --platform=linux --target=8.10.0 sharp
|
||||
npm install --arch=x64 --platform=linux --target=10.15.0 sharp
|
||||
```
|
||||
|
||||
Alternatively a Docker container closely matching the Lambda runtime can be used:
|
||||
|
||||
```sh
|
||||
rm -rf node_modules/sharp
|
||||
docker run -v "$PWD":/var/task lambci/lambda:build-nodejs8.10 npm install sharp
|
||||
docker run -v "$PWD":/var/task lambci/lambda:build-nodejs10.x npm install sharp
|
||||
```
|
||||
|
||||
To get the best performance select the largest memory available.
|
||||
|
@ -3,7 +3,6 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const copyFileSync = require('fs-copy-file-sync');
|
||||
const libvips = require('../lib/libvips');
|
||||
const npmLog = require('npmlog');
|
||||
|
||||
@ -24,7 +23,7 @@ if (process.platform === 'win32') {
|
||||
return /\.dll$/.test(filename);
|
||||
})
|
||||
.forEach(function (filename) {
|
||||
copyFileSync(
|
||||
fs.copyFileSync(
|
||||
path.join(vendorLibDir, filename),
|
||||
path.join(buildReleaseDir, filename)
|
||||
);
|
||||
|
@ -9,7 +9,6 @@ const npmLog = require('npmlog');
|
||||
const semver = require('semver');
|
||||
const simpleGet = require('simple-get');
|
||||
const tar = require('tar');
|
||||
const copyFileSync = require('fs-copy-file-sync');
|
||||
|
||||
const agent = require('../lib/agent');
|
||||
const libvips = require('../lib/libvips');
|
||||
@ -64,7 +63,7 @@ try {
|
||||
if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
|
||||
throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
|
||||
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.19.0')) {
|
||||
throw new Error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
// Download to per-process temporary file
|
||||
@ -97,7 +96,7 @@ try {
|
||||
fs.renameSync(tarPathTemp, tarPathCache);
|
||||
} catch (err) {
|
||||
// Fall back to copy and unlink
|
||||
copyFileSync(tarPathTemp, tarPathCache);
|
||||
fs.copyFileSync(tarPathTemp, tarPathCache);
|
||||
fs.unlinkSync(tarPathTemp);
|
||||
}
|
||||
extractTarball(tarPathCache);
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const deprecate = require('util').deprecate;
|
||||
|
||||
const is = require('./is');
|
||||
|
||||
/**
|
||||
@ -154,21 +152,11 @@ function composite (images) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @private
|
||||
*/
|
||||
function overlayWith (input, options) {
|
||||
const blend = (is.object(options) && options.cutout) ? 'dest-in' : 'over';
|
||||
return this.composite([Object.assign({ input, blend }, options)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate the Sharp prototype with composite-related functions.
|
||||
* @private
|
||||
*/
|
||||
module.exports = function (Sharp) {
|
||||
Sharp.prototype.composite = composite;
|
||||
Sharp.prototype.overlayWith = deprecate(overlayWith, 'overlayWith(input, options) is deprecated, use composite([{ input, ...options }]) instead');
|
||||
Sharp.blend = blend;
|
||||
};
|
||||
|
23
package.json
@ -93,39 +93,38 @@
|
||||
"vips"
|
||||
],
|
||||
"dependencies": {
|
||||
"color": "^3.1.1",
|
||||
"color": "^3.1.2",
|
||||
"detect-libc": "^1.0.3",
|
||||
"fs-copy-file-sync": "^1.1.1",
|
||||
"nan": "^2.13.2",
|
||||
"nan": "^2.14.0",
|
||||
"npmlog": "^4.1.2",
|
||||
"prebuild-install": "^5.3.0",
|
||||
"semver": "^6.0.0",
|
||||
"semver": "^6.1.2",
|
||||
"simple-get": "^3.0.3",
|
||||
"tar": "^4.4.8",
|
||||
"tar": "^4.4.10",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"async": "^2.6.2",
|
||||
"async": "^3.1.0",
|
||||
"cc": "^1.0.2",
|
||||
"decompress-zip": "^0.3.2",
|
||||
"documentation": "^10.0.0",
|
||||
"documentation": "^11.0.1",
|
||||
"exif-reader": "^1.0.2",
|
||||
"icc": "^1.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^6.1.4",
|
||||
"mock-fs": "^4.9.0",
|
||||
"nyc": "^14.0.0",
|
||||
"prebuild": "^8.2.1",
|
||||
"mock-fs": "^4.10.1",
|
||||
"nyc": "^14.1.1",
|
||||
"prebuild": "^9.0.0",
|
||||
"prebuild-ci": "^3.0.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"semistandard": "^13.0.1"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"config": {
|
||||
"libvips": "8.7.4"
|
||||
"libvips": "8.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=8.5.0"
|
||||
},
|
||||
"semistandard": {
|
||||
"env": [
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
// Verify platform and compiler compatibility
|
||||
|
||||
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 7))
|
||||
#error libvips version 8.7.0+ is required - see sharp.pixelplumbing.com/page/install
|
||||
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 8))
|
||||
#error libvips version 8.8.0+ is required - see sharp.pixelplumbing.com/page/install
|
||||
#endif
|
||||
|
||||
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
||||
|
@ -32,8 +32,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
@ -563,7 +563,7 @@ VImage::new_from_file( const char *name, VOption *options )
|
||||
}
|
||||
|
||||
VImage
|
||||
VImage::new_from_buffer( void *buf, size_t len, const char *option_string,
|
||||
VImage::new_from_buffer( const void *buf, size_t len, const char *option_string,
|
||||
VOption *options )
|
||||
{
|
||||
const char *operation_name;
|
||||
@ -588,6 +588,13 @@ VImage::new_from_buffer( void *buf, size_t len, const char *option_string,
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage
|
||||
VImage::new_from_buffer( const std::string &buf, const char *option_string,
|
||||
VOption *options )
|
||||
{
|
||||
return( new_from_buffer( buf.c_str(), buf.size(), option_string, options ) );
|
||||
}
|
||||
|
||||
VImage
|
||||
VImage::new_matrix( int width, int height )
|
||||
{
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <vips/vips8>
|
||||
#include <node.h>
|
||||
@ -30,6 +32,17 @@
|
||||
#include "operations.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define STAT64_STRUCT __stat64
|
||||
#define STAT64_FUNCTION _stat64
|
||||
#elif defined(__APPLE__)
|
||||
#define STAT64_STRUCT stat
|
||||
#define STAT64_FUNCTION stat
|
||||
#else
|
||||
#define STAT64_STRUCT stat64
|
||||
#define STAT64_FUNCTION stat64
|
||||
#endif
|
||||
|
||||
class PipelineWorker : public Nan::AsyncWorker {
|
||||
public:
|
||||
PipelineWorker(
|
||||
@ -1005,8 +1018,8 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
argv[2] = info;
|
||||
} else {
|
||||
// Add file size to info
|
||||
GStatBuf st;
|
||||
if (g_stat(baton->fileOut.data(), &st) == 0) {
|
||||
struct STAT64_STRUCT st;
|
||||
if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
|
||||
Set(info, New("size").ToLocalChecked(), New<v8::Uint32>(static_cast<uint32_t>(st.st_size)));
|
||||
}
|
||||
argv[1] = info;
|
||||
|
@ -194,7 +194,7 @@ struct PipelineBaton {
|
||||
blurSigma(0.0),
|
||||
brightness(1.0),
|
||||
saturation(1.0),
|
||||
hue(0.0),
|
||||
hue(0),
|
||||
medianSize(0),
|
||||
sharpenSigma(0.0),
|
||||
sharpenFlat(1.0),
|
||||
|
@ -127,7 +127,7 @@ class StatsWorker : public Nan::AsyncWorker {
|
||||
Set(channelStat, New("minY").ToLocalChecked(), New<v8::Number>(it->minY));
|
||||
Set(channelStat, New("maxX").ToLocalChecked(), New<v8::Number>(it->maxX));
|
||||
Set(channelStat, New("maxY").ToLocalChecked(), New<v8::Number>(it->maxY));
|
||||
channels->Set(i, channelStat);
|
||||
Set(channels, i, channelStat);
|
||||
}
|
||||
|
||||
Set(info, New("channels").ToLocalChecked(), channels);
|
||||
|
@ -8,17 +8,17 @@
|
||||
"test": "node perf && node random && node parallel"
|
||||
},
|
||||
"devDependencies": {
|
||||
"async": "^2.6.1",
|
||||
"async": "^3.1.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"gm": "^1.23.1",
|
||||
"imagemagick": "^0.1.3",
|
||||
"imagemagick-native": "^1.9.3",
|
||||
"jimp": "^0.5.3",
|
||||
"mapnik": "^4.0.1",
|
||||
"semver": "^5.5.1"
|
||||
"jimp": "^0.6.4",
|
||||
"mapnik": "^4.2.1",
|
||||
"semver": "^6.1.2"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=8.5.0"
|
||||
}
|
||||
}
|
||||
|
BIN
test/fixtures/alpha-layer-1-fill-low-alpha.png
vendored
Before Width: | Height: | Size: 222 KiB |
BIN
test/fixtures/alpha-layer-2-ink-low-alpha.png
vendored
Before Width: | Height: | Size: 89 KiB |
BIN
test/fixtures/alpha-layer-2-ink.png
vendored
Before Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 186 KiB |
BIN
test/fixtures/expected/alpha-layer-01-low-alpha.png
vendored
Before Width: | Height: | Size: 188 KiB |
BIN
test/fixtures/expected/alpha-layer-01.png
vendored
Before Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 259 KiB |
Before Width: | Height: | Size: 208 KiB |
BIN
test/fixtures/expected/alpha-layer-012-low-alpha.png
vendored
Before Width: | Height: | Size: 209 KiB |
BIN
test/fixtures/expected/alpha-layer-012.png
vendored
Before Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 221 KiB |
Before Width: | Height: | Size: 179 KiB |
BIN
test/fixtures/expected/alpha-layer-12-low-alpha.png
vendored
Before Width: | Height: | Size: 179 KiB |
BIN
test/fixtures/expected/alpha-layer-12.png
vendored
Before Width: | Height: | Size: 200 KiB |
BIN
test/fixtures/expected/crop-strategy-attention.jpg
vendored
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
test/fixtures/expected/svg-embedded.png
vendored
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 84 KiB |
3
test/fixtures/index.js
vendored
@ -80,9 +80,6 @@ module.exports = {
|
||||
inputPngWithTransparency16bit: getPath('tbgn2c16.png'), // http://www.schaik.com/pngsuite/tbgn2c16.png
|
||||
inputPngOverlayLayer0: getPath('alpha-layer-0-background.png'),
|
||||
inputPngOverlayLayer1: getPath('alpha-layer-1-fill.png'),
|
||||
inputPngOverlayLayer2: getPath('alpha-layer-2-ink.png'),
|
||||
inputPngOverlayLayer1LowAlpha: getPath('alpha-layer-1-fill-low-alpha.png'),
|
||||
inputPngOverlayLayer2LowAlpha: getPath('alpha-layer-2-ink-low-alpha.png'),
|
||||
inputPngAlphaPremultiplicationSmall: getPath('alpha-premultiply-1024x768-paper.png'),
|
||||
inputPngAlphaPremultiplicationLarge: getPath('alpha-premultiply-2048x1536-paper.png'),
|
||||
inputPngBooleanNoAlpha: getPath('bandbool.png'),
|
||||
|
@ -75,8 +75,8 @@ describe('Image metadata', function () {
|
||||
// XMP
|
||||
assert.strictEqual('object', typeof metadata.xmp);
|
||||
assert.strictEqual(true, metadata.xmp instanceof Buffer);
|
||||
assert.strictEqual(12495, metadata.xmp.byteLength);
|
||||
assert.strictEqual(metadata.xmp.indexOf(Buffer.from('http://ns.adobe.com/xap/1.0')), 0);
|
||||
assert.strictEqual(12466, metadata.xmp.byteLength);
|
||||
assert.strictEqual(metadata.xmp.indexOf(Buffer.from('<?xpacket begin="')), 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -1,589 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const assert = require('assert');
|
||||
|
||||
const fixtures = require('../fixtures');
|
||||
const sharp = require('../../');
|
||||
|
||||
// Helpers
|
||||
const getPaths = function (baseName, extension) {
|
||||
if (typeof extension === 'undefined') {
|
||||
extension = 'png';
|
||||
}
|
||||
return {
|
||||
actual: fixtures.path('output.' + baseName + '.' + extension),
|
||||
expected: fixtures.expected(baseName + '.' + extension)
|
||||
};
|
||||
};
|
||||
|
||||
// Test
|
||||
describe('Overlays', function () {
|
||||
it('Overlay transparent PNG file on solid background', function (done) {
|
||||
const paths = getPaths('alpha-layer-01');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay transparent PNG Buffer on solid background', function (done) {
|
||||
const paths = getPaths('alpha-layer-01');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.overlayWith(fs.readFileSync(fixtures.inputPngOverlayLayer1))
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay low-alpha transparent PNG on solid background', function (done) {
|
||||
const paths = getPaths('alpha-layer-01-low-alpha');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1LowAlpha)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite three transparent PNGs into one', function (done) {
|
||||
const paths = getPaths('alpha-layer-012');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1)
|
||||
.toBuffer(function (error, data) {
|
||||
if (error) return done(error);
|
||||
sharp(data)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer2)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite two transparent PNGs into one', function (done) {
|
||||
const paths = getPaths('alpha-layer-12');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer1)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer2)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite two low-alpha transparent PNGs into one', function (done) {
|
||||
const paths = getPaths('alpha-layer-12-low-alpha');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer1LowAlpha)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer2LowAlpha)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected, 2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite three low-alpha transparent PNGs into one', function (done) {
|
||||
const paths = getPaths('alpha-layer-012-low-alpha');
|
||||
|
||||
sharp(fixtures.inputPngOverlayLayer0)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1LowAlpha)
|
||||
.toBuffer(function (error, data) {
|
||||
if (error) return done(error);
|
||||
|
||||
sharp(data)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer2LowAlpha)
|
||||
.toFile(paths.actual, function (error) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite rgb+alpha PNG onto JPEG', function (done) {
|
||||
const paths = getPaths('overlay-jpeg-with-rgb', 'jpg');
|
||||
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(2048, 1536)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1)
|
||||
.toFile(paths.actual, function (error, info) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected, 102);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite greyscale+alpha PNG onto JPEG', function (done) {
|
||||
const paths = getPaths('overlay-jpeg-with-greyscale', 'jpg');
|
||||
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400, 300)
|
||||
.overlayWith(fixtures.inputPngWithGreyAlpha)
|
||||
.toFile(paths.actual, function (error, info) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected, 102);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite WebP onto JPEG', function (done) {
|
||||
const paths = getPaths('overlay-jpeg-with-webp', 'jpg');
|
||||
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(300, 300)
|
||||
.overlayWith(fixtures.inputWebPWithTransparency)
|
||||
.toFile(paths.actual, function (error, info) {
|
||||
if (error) return done(error);
|
||||
fixtures.assertMaxColourDistance(paths.actual, paths.expected, 102);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite JPEG onto PNG, ensure premultiply', function (done) {
|
||||
sharp(fixtures.inputPngOverlayLayer1)
|
||||
.overlayWith(fixtures.inputJpgWithLandscapeExif1)
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(true, info.premultiplied);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite opaque JPEG onto JPEG, ensure premultiply', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.overlayWith(fixtures.inputJpgWithLandscapeExif1)
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(true, info.premultiplied);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail when overlay is larger', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(320)
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1)
|
||||
.toBuffer(function (error) {
|
||||
assert.strictEqual(true, error instanceof Error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail with empty String parameter', function () {
|
||||
assert.throws(function () {
|
||||
sharp().overlayWith('');
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail with non-String parameter', function () {
|
||||
assert.throws(function () {
|
||||
sharp().overlayWith(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail with unsupported gravity', function () {
|
||||
assert.throws(function () {
|
||||
sharp()
|
||||
.overlayWith(fixtures.inputPngOverlayLayer1, {
|
||||
gravity: 9
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Empty options', function () {
|
||||
assert.doesNotThrow(function () {
|
||||
sharp().overlayWith(fixtures.inputPngOverlayLayer1, {});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overlay with numeric gravity', function () {
|
||||
Object.keys(sharp.gravity).forEach(function (gravity) {
|
||||
it(gravity, function (done) {
|
||||
const expected = fixtures.expected('overlay-gravity-' + gravity + '.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
gravity: gravity
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(65, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overlay with string-based gravity', function () {
|
||||
Object.keys(sharp.gravity).forEach(function (gravity) {
|
||||
it(gravity, function (done) {
|
||||
const expected = fixtures.expected('overlay-gravity-' + gravity + '.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
gravity: sharp.gravity[gravity]
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(65, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overlay with tile enabled and gravity', function () {
|
||||
Object.keys(sharp.gravity).forEach(function (gravity) {
|
||||
it(gravity, function (done) {
|
||||
const expected = fixtures.expected('overlay-tile-gravity-' + gravity + '.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
tile: true,
|
||||
gravity: gravity
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(65, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overlay with top-left offsets', function () {
|
||||
it('Overlay with 10px top & 10px left offsets', function (done) {
|
||||
const expected = fixtures.expected('overlay-valid-offsets-10-10.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
top: 10,
|
||||
left: 10
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with 100px top & 300px left offsets', function (done) {
|
||||
const expected = fixtures.expected('overlay-valid-offsets-100-300.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
top: 100,
|
||||
left: 300
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with only top offset', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
top: 1000
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with only left offset', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
left: 1000
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with negative offsets', function () {
|
||||
assert.throws(function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
top: -1000,
|
||||
left: -1000
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with 0 offset', function (done) {
|
||||
const expected = fixtures.expected('overlay-offset-0.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
top: 0,
|
||||
left: 0
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with offset and gravity', function (done) {
|
||||
const expected = fixtures.expected('overlay-offset-with-gravity.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
left: 10,
|
||||
top: 10,
|
||||
gravity: 4
|
||||
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with offset and gravity and tile', function (done) {
|
||||
const expected = fixtures.expected('overlay-offset-with-gravity-tile.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
left: 10,
|
||||
top: 10,
|
||||
gravity: 4,
|
||||
tile: true
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with offset and tile', function (done) {
|
||||
const expected = fixtures.expected('overlay-offset-with-tile.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
left: 10,
|
||||
top: 10,
|
||||
tile: true
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with invalid tile option', function () {
|
||||
assert.throws(function () {
|
||||
sharp().overlayWith('ignore', { tile: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay with very large offset', function (done) {
|
||||
const expected = fixtures.expected('overlay-very-large-offset.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
left: 10000,
|
||||
top: 10000
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Overlay 100x100 with 50x50 so bottom edges meet', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(50, 50)
|
||||
.toBuffer(function (err, overlay) {
|
||||
if (err) throw err;
|
||||
sharp(fixtures.inputJpgWithLandscapeExif1)
|
||||
.resize(100, 100)
|
||||
.overlayWith(overlay, {
|
||||
top: 50,
|
||||
left: 40
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(100, info.width);
|
||||
assert.strictEqual(100, info.height);
|
||||
fixtures.assertSimilar(fixtures.expected('overlay-bottom-edges-meet.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('With tile enabled and image rotated 90 degrees', function (done) {
|
||||
const expected = fixtures.expected('overlay-tile-rotated90.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.rotate(90)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
tile: true
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(98, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('With tile enabled and image rotated 90 degrees and gravity northwest', function (done) {
|
||||
const expected = fixtures.expected('overlay-tile-rotated90-gravity-northwest.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.rotate(90)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
tile: true,
|
||||
gravity: 'northwest'
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(98, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overlay with cutout enabled and gravity', function () {
|
||||
Object.keys(sharp.gravity).forEach(function (gravity) {
|
||||
it(gravity, function (done) {
|
||||
const expected = fixtures.expected('overlay-cutout-gravity-' + gravity + '.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
cutout: true,
|
||||
gravity: gravity
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(65, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('With cutout enabled and image rotated 90 degrees', function (done) {
|
||||
const expected = fixtures.expected('overlay-cutout-rotated90.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.rotate(90)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
cutout: true
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(98, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('With cutout enabled and image rotated 90 degrees and gravity northwest', function (done) {
|
||||
const expected = fixtures.expected('overlay-cutout-rotated90-gravity-northwest.jpg');
|
||||
sharp(fixtures.inputJpg)
|
||||
.rotate(90)
|
||||
.resize(80)
|
||||
.overlayWith(fixtures.inputPngWithTransparency16bit, {
|
||||
cutout: true,
|
||||
gravity: 'northwest'
|
||||
})
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(98, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
fixtures.assertSimilar(expected, data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite RGBA raw buffer onto JPEG', function (done) {
|
||||
sharp(fixtures.inputPngOverlayLayer1)
|
||||
.raw()
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(2048, 1536)
|
||||
.overlayWith(data, { raw: info })
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(true, info.premultiplied);
|
||||
fixtures.assertSimilar(fixtures.expected('overlay-jpeg-with-rgb.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Returns an error when called with an invalid file', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.overlayWith('notfound.png')
|
||||
.toBuffer(function (err) {
|
||||
assert(err instanceof Error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Composite JPEG onto JPEG', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(480, 320)
|
||||
.overlayWith(fixtures.inputJpgBooleanTest)
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
assert.strictEqual(480, info.width);
|
||||
assert.strictEqual(320, info.height);
|
||||
assert.strictEqual(3, info.channels);
|
||||
assert.strictEqual(true, info.premultiplied);
|
||||
fixtures.assertSimilar(fixtures.expected('overlay-jpeg-with-jpeg.jpg'), data, done);
|
||||
});
|
||||
});
|
||||
});
|
@ -338,7 +338,7 @@ describe('Resize fit=cover', function () {
|
||||
assert.strictEqual(3, info.channels);
|
||||
assert.strictEqual(80, info.width);
|
||||
assert.strictEqual(320, info.height);
|
||||
assert.strictEqual(-143, info.cropOffsetLeft);
|
||||
assert.strictEqual(-107, info.cropOffsetLeft);
|
||||
assert.strictEqual(0, info.cropOffsetTop);
|
||||
fixtures.assertSimilar(fixtures.expected('crop-strategy-attention.jpg'), data, done);
|
||||
});
|
||||
|
@ -109,7 +109,7 @@ describe('TIFF', function () {
|
||||
.toFile(fixtures.outputTiff, (err, info) => {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('tiff', info.format);
|
||||
assert(info.size === startSize);
|
||||
assert.strictEqual(startSize, info.size);
|
||||
rimraf(fixtures.outputTiff, done);
|
||||
});
|
||||
});
|
||||
|