mirror of
https://github.com/lovell/sharp.git
synced 2026-02-06 06:36:17 +01:00
Compare commits
18 Commits
v0.33.0-al
...
v0.33.0-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c1551bdc9 | ||
|
|
bdcf02695f | ||
|
|
d206fd5392 | ||
|
|
0bd1715f36 | ||
|
|
2e7c60675b | ||
|
|
7caaa8e22b | ||
|
|
839c92bf3d | ||
|
|
28aa176957 | ||
|
|
0f24f0f214 | ||
|
|
655da113c8 | ||
|
|
159b986cdd | ||
|
|
069d1786f5 | ||
|
|
f43829a16a | ||
|
|
65e61ad001 | ||
|
|
0107a4de81 | ||
|
|
337ce7b1c2 | ||
|
|
3719f79065 | ||
|
|
8d1747aa6a |
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@@ -121,27 +121,42 @@ jobs:
|
|||||||
github-runner-qemu:
|
github-runner-qemu:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
name: linux-arm - Node.js 18 - prebuild
|
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: linux-arm
|
||||||
|
run_on_arch: armv6
|
||||||
|
nodejs_arch: armv6l
|
||||||
|
nodejs_hostname: unofficial-builds.nodejs.org
|
||||||
|
nodejs_version: "18.17.0"
|
||||||
|
nodejs_version_major: 18
|
||||||
|
- platform: linux-s390x
|
||||||
|
run_on_arch: s390x
|
||||||
|
nodejs_arch: s390x
|
||||||
|
nodejs_hostname: nodejs.org
|
||||||
|
nodejs_version: "18.17.0"
|
||||||
|
nodejs_version_major: 18
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: uraimo/run-on-arch-action@v2
|
- uses: uraimo/run-on-arch-action@v2
|
||||||
with:
|
with:
|
||||||
arch: armv6
|
arch: ${{ matrix.run_on_arch }}
|
||||||
distro: buster
|
distro: buster
|
||||||
env: |
|
env: |
|
||||||
nodejs_version: "18.17.0"
|
|
||||||
prebuild_upload: "${{ startsWith(github.ref, 'refs/tags/') && secrets.GITHUB_TOKEN || '' }}"
|
prebuild_upload: "${{ startsWith(github.ref, 'refs/tags/') && secrets.GITHUB_TOKEN || '' }}"
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y fontconfig fonts-noto-core g++ git libatomic1 make python3 xz-utils
|
apt-get install -y curl g++ git libatomic1 make python3 xz-utils
|
||||||
mkdir /opt/nodejs
|
mkdir /opt/nodejs
|
||||||
curl --silent https://unofficial-builds.nodejs.org/download/release/v${nodejs_version}/node-v${nodejs_version}-linux-armv6l.tar.xz | tar xJC /opt/nodejs --strip-components=1
|
curl --silent https://${{ matrix.nodejs_hostname }}/download/release/v${{ matrix.nodejs_version}}/node-v${{ matrix.nodejs_version}}-linux-${{ matrix.nodejs_arch }}.tar.xz | tar xJC /opt/nodejs --strip-components=1
|
||||||
export PATH=$PATH:/opt/nodejs/bin
|
export PATH=$PATH:/opt/nodejs/bin
|
||||||
npm install --build-from-source
|
npm install --build-from-source
|
||||||
npx mocha --no-config --spec=test/unit/io.js
|
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
|
||||||
npm run package-from-local-build
|
npm run package-from-local-build
|
||||||
npm pkg set "optionalDependencies.@img/sharp-linux-arm=file:./npm/linux-arm"
|
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
|
||||||
npm run clean
|
npm run clean
|
||||||
npm install --ignore-scripts
|
npm install --ignore-scripts
|
||||||
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
|
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"runtime": "napi",
|
"runtime": "napi",
|
||||||
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll|libglib-.+\\.dll|libgobject-.+\\.dll)",
|
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll)",
|
||||||
"prerelease": true,
|
"prerelease": true,
|
||||||
"strip": true
|
"strip": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@
|
|||||||
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||||
|
|
||||||
The typical use case for this high speed Node.js module
|
The typical use case for this high speed Node-API module
|
||||||
is to convert large images in common formats to
|
is to convert large images in common formats to
|
||||||
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
||||||
|
|
||||||
|
It can be used with all JavaScript runtimes
|
||||||
|
that provide support for Node-API v9, including
|
||||||
|
Node.js >= 18.17.0, Deno and Bun.
|
||||||
|
|
||||||
Resizing an image is typically 4x-5x faster than using the
|
Resizing an image is typically 4x-5x faster than using the
|
||||||
quickest ImageMagick and GraphicsMagick settings
|
quickest ImageMagick and GraphicsMagick settings
|
||||||
due to its use of [libvips](https://github.com/libvips/libvips).
|
due to its use of [libvips](https://github.com/libvips/libvips).
|
||||||
@@ -16,7 +20,7 @@ Lanczos resampling ensures quality is not sacrificed for speed.
|
|||||||
As well as image resizing, operations such as
|
As well as image resizing, operations such as
|
||||||
rotation, extraction, compositing and gamma correction are available.
|
rotation, extraction, compositing and gamma correction are available.
|
||||||
|
|
||||||
Most modern macOS, Windows and Linux systems running Node.js >= 18.17.0
|
Most modern macOS, Windows and Linux systems
|
||||||
do not require any additional install or runtime dependencies.
|
do not require any additional install or runtime dependencies.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|||||||
@@ -2,10 +2,14 @@
|
|||||||
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||||
|
|
||||||
The typical use case for this high speed Node.js module
|
The typical use case for this high speed Node-API module
|
||||||
is to convert large images in common formats to
|
is to convert large images in common formats to
|
||||||
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
||||||
|
|
||||||
|
It can be used with all JavaScript runtimes
|
||||||
|
that provide support for Node-API v9, including
|
||||||
|
Node.js >= 18.17.0, Deno and Bun.
|
||||||
|
|
||||||
Resizing an image is typically 4x-5x faster than using the
|
Resizing an image is typically 4x-5x faster than using the
|
||||||
quickest ImageMagick and GraphicsMagick settings
|
quickest ImageMagick and GraphicsMagick settings
|
||||||
due to its use of [libvips](https://github.com/libvips/libvips).
|
due to its use of [libvips](https://github.com/libvips/libvips).
|
||||||
@@ -16,7 +20,7 @@ Lanczos resampling ensures quality is not sacrificed for speed.
|
|||||||
As well as image resizing, operations such as
|
As well as image resizing, operations such as
|
||||||
rotation, extraction, compositing and gamma correction are available.
|
rotation, extraction, compositing and gamma correction are available.
|
||||||
|
|
||||||
Most modern macOS, Windows and Linux systems running Node.js >= 14.15.0
|
Most modern macOS, Windows and Linux systems
|
||||||
do not require any additional install or runtime dependencies.
|
do not require any additional install or runtime dependencies.
|
||||||
|
|
||||||
### Formats
|
### Formats
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_st
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| [input] | <code>Buffer</code> \| <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Uint8ClampedArray</code> \| <code>Int8Array</code> \| <code>Uint16Array</code> \| <code>Int16Array</code> \| <code>Uint32Array</code> \| <code>Int32Array</code> \| <code>Float32Array</code> \| <code>Float64Array</code> \| <code>string</code> | | if present, can be a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or a TypedArray containing raw pixel image data, or a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file. JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present. |
|
| [input] | <code>Buffer</code> \| <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Uint8ClampedArray</code> \| <code>Int8Array</code> \| <code>Uint16Array</code> \| <code>Int16Array</code> \| <code>Uint32Array</code> \| <code>Int32Array</code> \| <code>Float32Array</code> \| <code>Float64Array</code> \| <code>string</code> | | if present, can be a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or a TypedArray containing raw pixel image data, or a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file. JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present. |
|
||||||
| [options] | <code>Object</code> | | if present, is an Object with optional attributes. |
|
| [options] | <code>Object</code> | | if present, is an Object with optional attributes. |
|
||||||
| [options.failOn] | <code>string</code> | <code>"'warning'"</code> | when to abort processing of invalid pixel data, one of (in order of sensitivity): 'none' (least), 'truncated', 'error' or 'warning' (most), higher levels imply lower levels, invalid metadata will always abort. |
|
| [options.failOn] | <code>string</code> | <code>"'warning'"</code> | When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort. |
|
||||||
| [options.limitInputPixels] | <code>number</code> \| <code>boolean</code> | <code>268402689</code> | Do not process input images where the number of pixels (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted. An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). |
|
| [options.limitInputPixels] | <code>number</code> \| <code>boolean</code> | <code>268402689</code> | Do not process input images where the number of pixels (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted. An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). |
|
||||||
| [options.unlimited] | <code>boolean</code> | <code>false</code> | Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF). |
|
| [options.unlimited] | <code>boolean</code> | <code>false</code> | Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF). |
|
||||||
| [options.sequentialRead] | <code>boolean</code> | <code>true</code> | Set this to `false` to use random access rather than sequential read. Some operations will do this automatically. |
|
| [options.sequentialRead] | <code>boolean</code> | <code>true</code> | Set this to `false` to use random access rather than sequential read. Some operations will do this automatically. |
|
||||||
|
|||||||
@@ -466,6 +466,7 @@ instead of providing `xres` and `yres` in pixels/mm.
|
|||||||
| [options.yres] | <code>number</code> | <code>1.0</code> | vertical resolution in pixels/mm |
|
| [options.yres] | <code>number</code> | <code>1.0</code> | vertical resolution in pixels/mm |
|
||||||
| [options.resolutionUnit] | <code>string</code> | <code>"'inch'"</code> | resolution unit options: inch, cm |
|
| [options.resolutionUnit] | <code>string</code> | <code>"'inch'"</code> | resolution unit options: inch, cm |
|
||||||
| [options.bitdepth] | <code>number</code> | <code>8</code> | reduce bitdepth to 1, 2 or 4 bit |
|
| [options.bitdepth] | <code>number</code> | <code>8</code> | reduce bitdepth to 1, 2 or 4 bit |
|
||||||
|
| [options.miniswhite] | <code>boolean</code> | <code>false</code> | write 1-bit images as miniswhite |
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ sharp(input)
|
|||||||
|
|
||||||
|
|
||||||
## trim
|
## trim
|
||||||
> trim(trim) ⇒ <code>Sharp</code>
|
> trim([options]) ⇒ <code>Sharp</code>
|
||||||
|
|
||||||
Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
||||||
|
|
||||||
@@ -259,8 +259,7 @@ Images with an alpha channel will use the combined bounding box of alpha and non
|
|||||||
|
|
||||||
If the result of this operation would trim an image to nothing then no change is made.
|
If the result of this operation would trim an image to nothing then no change is made.
|
||||||
|
|
||||||
The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
|
The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
||||||
will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
|
||||||
|
|
||||||
|
|
||||||
**Throws**:
|
**Throws**:
|
||||||
@@ -270,46 +269,44 @@ will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
|||||||
|
|
||||||
| Param | Type | Default | Description |
|
| Param | Type | Default | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| trim | <code>string</code> \| <code>number</code> \| <code>Object</code> | | the specific background colour to trim, the threshold for doing so or an Object with both. |
|
| [options] | <code>Object</code> | | |
|
||||||
| [trim.background] | <code>string</code> \| <code>Object</code> | <code>"'top-left pixel'"</code> | background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel. |
|
| [options.background] | <code>string</code> \| <code>Object</code> | <code>"'top-left pixel'"</code> | Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel. |
|
||||||
| [trim.threshold] | <code>number</code> | <code>10</code> | the allowed difference from the above colour, a positive number. |
|
| [options.threshold] | <code>number</code> | <code>10</code> | Allowed difference from the above colour, a positive number. |
|
||||||
|
| [options.lineArt] | <code>boolean</code> | <code>false</code> | Does the input more closely resemble line art (e.g. vector) rather than being photographic? |
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
// Trim pixels with a colour similar to that of the top-left pixel.
|
// Trim pixels with a colour similar to that of the top-left pixel.
|
||||||
sharp(input)
|
await sharp(input)
|
||||||
.trim()
|
.trim()
|
||||||
.toFile(output, function(err, info) {
|
.toFile(output);
|
||||||
...
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
// Trim pixels with the exact same colour as that of the top-left pixel.
|
// Trim pixels with the exact same colour as that of the top-left pixel.
|
||||||
sharp(input)
|
await sharp(input)
|
||||||
.trim(0)
|
.trim({
|
||||||
.toFile(output, function(err, info) {
|
threshold: 0
|
||||||
...
|
})
|
||||||
});
|
.toFile(output);
|
||||||
```
|
```
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
// Trim only pixels with a similar colour to red.
|
// Assume input is line art and trim only pixels with a similar colour to red.
|
||||||
sharp(input)
|
const output = await sharp(input)
|
||||||
.trim("#FF0000")
|
.trim({
|
||||||
.toFile(output, function(err, info) {
|
background: "#FF0000",
|
||||||
...
|
lineArt: true
|
||||||
});
|
})
|
||||||
|
.toBuffer();
|
||||||
```
|
```
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
// Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
|
// Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
|
||||||
sharp(input)
|
const output = await sharp(input)
|
||||||
.trim({
|
.trim({
|
||||||
background: "yellow",
|
background: "yellow",
|
||||||
threshold: 42,
|
threshold: 42,
|
||||||
})
|
})
|
||||||
.toFile(output, function(err, info) {
|
.toBuffer();
|
||||||
...
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## v0.33 - *gauge*
|
## v0.33 - *gauge*
|
||||||
|
|
||||||
Requires libvips v8.14.5
|
Requires libvips v8.15.0
|
||||||
|
|
||||||
### v0.33.0 - TBD
|
### v0.33.0 - TBD
|
||||||
|
|
||||||
@@ -14,6 +14,9 @@ Requires libvips v8.14.5
|
|||||||
|
|
||||||
* Remove `sharp.vendor`.
|
* Remove `sharp.vendor`.
|
||||||
|
|
||||||
|
* Options for `trim` operation must be an Object, add new `lineArt` option.
|
||||||
|
[#2363](https://github.com/lovell/sharp/issues/2363)
|
||||||
|
|
||||||
* Ensure all `Error` objects contain a `stack` property.
|
* Ensure all `Error` objects contain a `stack` property.
|
||||||
[#3653](https://github.com/lovell/sharp/issues/3653)
|
[#3653](https://github.com/lovell/sharp/issues/3653)
|
||||||
|
|
||||||
@@ -23,6 +26,17 @@ Requires libvips v8.14.5
|
|||||||
* Ensure correct interpretation of 16-bit raw input.
|
* Ensure correct interpretation of 16-bit raw input.
|
||||||
[#3808](https://github.com/lovell/sharp/issues/3808)
|
[#3808](https://github.com/lovell/sharp/issues/3808)
|
||||||
|
|
||||||
|
* Add support for `miniswhite` when using TIFF output.
|
||||||
|
[#3812](https://github.com/lovell/sharp/pull/3812)
|
||||||
|
[@dnsbty](https://github.com/dnsbty)
|
||||||
|
|
||||||
|
* TypeScript: add missing definition for `withMetadata` boolean.
|
||||||
|
[#3823](https://github.com/lovell/sharp/pull/3823)
|
||||||
|
[@uhthomas](https://github.com/uhthomas)
|
||||||
|
|
||||||
|
* Ensure multi-page extract remains sequential.
|
||||||
|
[#3837](https://github.com/lovell/sharp/issues/3837)
|
||||||
|
|
||||||
## v0.32 - *flow*
|
## v0.32 - *flow*
|
||||||
|
|
||||||
Requires libvips v8.14.5
|
Requires libvips v8.14.5
|
||||||
|
|||||||
@@ -275,3 +275,6 @@ GitHub: https://github.com/LachlanNewman
|
|||||||
|
|
||||||
Name: BJJ
|
Name: BJJ
|
||||||
GitHub: https://github.com/bianjunjie1981
|
GitHub: https://github.com/bianjunjie1981
|
||||||
|
|
||||||
|
Name: Dennis Beatty
|
||||||
|
GitHub: https://github.com/dnsbty
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
Works with your choice of JavaScript package manager.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install sharp
|
npm install sharp
|
||||||
```
|
```
|
||||||
@@ -9,14 +11,20 @@ pnpm add sharp
|
|||||||
```
|
```
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn add sharp
|
yarn add sharp # v3 recommended, Plug'n'Play unsupported
|
||||||
```
|
```
|
||||||
|
|
||||||
Yarn Plug'n'Play is unsupported.
|
```sh
|
||||||
|
bun add sharp
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
deno run --allow-ffi ...
|
||||||
|
```
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
* Node.js >= 18.17.0
|
* Node-API v9 compatible runtime e.g. Node.js >= 18.17.0
|
||||||
|
|
||||||
## Prebuilt binaries
|
## Prebuilt binaries
|
||||||
|
|
||||||
@@ -24,9 +32,10 @@ Ready-compiled sharp and libvips binaries are provided for use on the most commo
|
|||||||
|
|
||||||
* macOS x64 (>= 10.13)
|
* macOS x64 (>= 10.13)
|
||||||
* macOS ARM64
|
* macOS ARM64
|
||||||
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
|
||||||
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
|
||||||
* Linux ARM (glibc >= 2.28)
|
* Linux ARM (glibc >= 2.28)
|
||||||
|
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
||||||
|
* Linux s390x (glibc >= 2.28)
|
||||||
|
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
||||||
* Windows x64
|
* Windows x64
|
||||||
* Windows x86
|
* Windows x86
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -121,7 +121,7 @@ const debuglog = util.debuglog('sharp');
|
|||||||
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
||||||
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
||||||
* @param {Object} [options] - if present, is an Object with optional attributes.
|
* @param {Object} [options] - if present, is an Object with optional attributes.
|
||||||
* @param {string} [options.failOn='warning'] - when to abort processing of invalid pixel data, one of (in order of sensitivity): 'none' (least), 'truncated', 'error' or 'warning' (most), higher levels imply lower levels, invalid metadata will always abort.
|
* @param {string} [options.failOn='warning'] - When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort.
|
||||||
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
||||||
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
||||||
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
||||||
@@ -230,7 +230,8 @@ const Sharp = function (input, options) {
|
|||||||
threshold: 0,
|
threshold: 0,
|
||||||
thresholdGrayscale: true,
|
thresholdGrayscale: true,
|
||||||
trimBackground: [],
|
trimBackground: [],
|
||||||
trimThreshold: 0,
|
trimThreshold: -1,
|
||||||
|
trimLineArt: false,
|
||||||
gamma: 0,
|
gamma: 0,
|
||||||
gammaOut: 0,
|
gammaOut: 0,
|
||||||
greyscale: false,
|
greyscale: false,
|
||||||
@@ -305,6 +306,7 @@ const Sharp = function (input, options) {
|
|||||||
tiffCompression: 'jpeg',
|
tiffCompression: 'jpeg',
|
||||||
tiffPredictor: 'horizontal',
|
tiffPredictor: 'horizontal',
|
||||||
tiffPyramid: false,
|
tiffPyramid: false,
|
||||||
|
tiffMiniswhite: false,
|
||||||
tiffBitdepth: 8,
|
tiffBitdepth: 8,
|
||||||
tiffTile: false,
|
tiffTile: false,
|
||||||
tiffTileHeight: 256,
|
tiffTileHeight: 256,
|
||||||
|
|||||||
12
lib/index.d.ts
vendored
12
lib/index.d.ts
vendored
@@ -847,11 +847,11 @@ declare namespace sharp {
|
|||||||
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
||||||
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
||||||
* The info response Object will contain trimOffsetLeft and trimOffsetTop properties.
|
* The info response Object will contain trimOffsetLeft and trimOffsetTop properties.
|
||||||
* @param trim The specific background colour to trim, the threshold for doing so or an Object with both.
|
* @param options trim options
|
||||||
* @throws {Error} Invalid parameters
|
* @throws {Error} Invalid parameters
|
||||||
* @returns A sharp instance that can be used to chain operations
|
* @returns A sharp instance that can be used to chain operations
|
||||||
*/
|
*/
|
||||||
trim(trim?: string | number | TrimOptions): Sharp;
|
trim(options?: TrimOptions): Sharp;
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
@@ -1234,6 +1234,8 @@ declare namespace sharp {
|
|||||||
yres?: number | undefined;
|
yres?: number | undefined;
|
||||||
/** Reduce bitdepth to 1, 2 or 4 bit (optional, default 8) */
|
/** Reduce bitdepth to 1, 2 or 4 bit (optional, default 8) */
|
||||||
bitdepth?: 1 | 2 | 4 | 8 | undefined;
|
bitdepth?: 1 | 2 | 4 | 8 | undefined;
|
||||||
|
/** Write 1-bit images as miniswhite (optional, default false) */
|
||||||
|
miniswhite?: boolean | undefined;
|
||||||
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
||||||
resolutionUnit?: 'inch' | 'cm' | undefined;
|
resolutionUnit?: 'inch' | 'cm' | undefined;
|
||||||
}
|
}
|
||||||
@@ -1340,10 +1342,12 @@ declare namespace sharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface TrimOptions {
|
interface TrimOptions {
|
||||||
/** background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */
|
/** Background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */
|
||||||
background?: Color | undefined;
|
background?: Color | undefined;
|
||||||
/** the allowed difference from the above colour, a positive number. (optional, default `10`) */
|
/** Allowed difference from the above colour, a positive number. (optional, default 10) */
|
||||||
threshold?: number | undefined;
|
threshold?: number | undefined;
|
||||||
|
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
||||||
|
lineArt?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RawOptions {
|
interface RawOptions {
|
||||||
|
|||||||
@@ -782,6 +782,7 @@ function trySetAnimationOptions (source, target) {
|
|||||||
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
||||||
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
||||||
* @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
|
* @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
|
||||||
|
* @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
@@ -819,6 +820,10 @@ function tiff (options) {
|
|||||||
throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
|
throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// miniswhite
|
||||||
|
if (is.defined(options.miniswhite)) {
|
||||||
|
this._setBooleanOption('tiffMiniswhite', options.miniswhite);
|
||||||
|
}
|
||||||
// pyramid
|
// pyramid
|
||||||
if (is.defined(options.pyramid)) {
|
if (is.defined(options.pyramid)) {
|
||||||
this._setBooleanOption('tiffPyramid', options.pyramid);
|
this._setBooleanOption('tiffPyramid', options.pyramid);
|
||||||
|
|||||||
@@ -494,70 +494,67 @@ function extract (options) {
|
|||||||
*
|
*
|
||||||
* If the result of this operation would trim an image to nothing then no change is made.
|
* If the result of this operation would trim an image to nothing then no change is made.
|
||||||
*
|
*
|
||||||
* The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
|
* The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
||||||
* will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // Trim pixels with a colour similar to that of the top-left pixel.
|
* // Trim pixels with a colour similar to that of the top-left pixel.
|
||||||
* sharp(input)
|
* await sharp(input)
|
||||||
* .trim()
|
* .trim()
|
||||||
* .toFile(output, function(err, info) {
|
* .toFile(output);
|
||||||
* ...
|
*
|
||||||
* });
|
|
||||||
* @example
|
* @example
|
||||||
* // Trim pixels with the exact same colour as that of the top-left pixel.
|
* // Trim pixels with the exact same colour as that of the top-left pixel.
|
||||||
* sharp(input)
|
* await sharp(input)
|
||||||
* .trim(0)
|
* .trim({
|
||||||
* .toFile(output, function(err, info) {
|
* threshold: 0
|
||||||
* ...
|
* })
|
||||||
* });
|
* .toFile(output);
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* // Trim only pixels with a similar colour to red.
|
* // Assume input is line art and trim only pixels with a similar colour to red.
|
||||||
* sharp(input)
|
* const output = await sharp(input)
|
||||||
* .trim("#FF0000")
|
* .trim({
|
||||||
* .toFile(output, function(err, info) {
|
* background: "#FF0000",
|
||||||
* ...
|
* lineArt: true
|
||||||
* });
|
* })
|
||||||
|
* .toBuffer();
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
|
* // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
|
||||||
* sharp(input)
|
* const output = await sharp(input)
|
||||||
* .trim({
|
* .trim({
|
||||||
* background: "yellow",
|
* background: "yellow",
|
||||||
* threshold: 42,
|
* threshold: 42,
|
||||||
* })
|
* })
|
||||||
* .toFile(output, function(err, info) {
|
* .toBuffer();
|
||||||
* ...
|
|
||||||
* });
|
|
||||||
*
|
*
|
||||||
* @param {string|number|Object} trim - the specific background colour to trim, the threshold for doing so or an Object with both.
|
* @param {Object} [options]
|
||||||
* @param {string|Object} [trim.background='top-left pixel'] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
|
* @param {string|Object} [options.background='top-left pixel'] - Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
|
||||||
* @param {number} [trim.threshold=10] - the allowed difference from the above colour, a positive number.
|
* @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number.
|
||||||
|
* @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic?
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid parameters
|
* @throws {Error} Invalid parameters
|
||||||
*/
|
*/
|
||||||
function trim (trim) {
|
function trim (options) {
|
||||||
if (!is.defined(trim)) {
|
this.options.trimThreshold = 10;
|
||||||
this.options.trimThreshold = 10;
|
if (is.defined(options)) {
|
||||||
} else if (is.string(trim)) {
|
if (is.object(options)) {
|
||||||
this._setBackgroundColourOption('trimBackground', trim);
|
if (is.defined(options.background)) {
|
||||||
this.options.trimThreshold = 10;
|
this._setBackgroundColourOption('trimBackground', options.background);
|
||||||
} else if (is.number(trim)) {
|
}
|
||||||
if (trim >= 0) {
|
if (is.defined(options.threshold)) {
|
||||||
this.options.trimThreshold = trim;
|
if (is.number(options.threshold) && options.threshold >= 0) {
|
||||||
|
this.options.trimThreshold = options.threshold;
|
||||||
|
} else {
|
||||||
|
throw is.invalidParameterError('threshold', 'positive number', options.threshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is.defined(options.lineArt)) {
|
||||||
|
this._setBooleanOption('trimLineArt', options.lineArt);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw is.invalidParameterError('threshold', 'positive number', trim);
|
throw is.invalidParameterError('trim', 'object', options);
|
||||||
}
|
}
|
||||||
} else if (is.object(trim)) {
|
|
||||||
this._setBackgroundColourOption('trimBackground', trim.background);
|
|
||||||
if (!is.defined(trim.threshold)) {
|
|
||||||
this.options.trimThreshold = 10;
|
|
||||||
} else if (is.number(trim.threshold) && trim.threshold >= 0) {
|
|
||||||
this.options.trimThreshold = trim.threshold;
|
|
||||||
} else {
|
|
||||||
throw is.invalidParameterError('threshold', 'positive number', trim);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw is.invalidParameterError('trim', 'string, number or object', trim);
|
|
||||||
}
|
}
|
||||||
if (isRotationExpected(this.options)) {
|
if (isRotationExpected(this.options)) {
|
||||||
this.options.rotateBeforePreExtract = true;
|
this.options.rotateBeforePreExtract = true;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-darwin-arm64",
|
"name": "@img/sharp-darwin-arm64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with macOS ARM64",
|
"description": "Prebuilt sharp for use with macOS 64-bit ARM",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-darwin-arm64": "0.0.1"
|
"@img/sharp-libvips-darwin-arm64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-darwin-x64",
|
"name": "@img/sharp-darwin-x64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with macOS x64",
|
"description": "Prebuilt sharp for use with macOS x64",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-darwin-x64": "0.0.1"
|
"@img/sharp-libvips-darwin-x64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-arm",
|
"name": "@img/sharp-linux-arm",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
|
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linux-arm": "0.0.1"
|
"@img/sharp-libvips-linux-arm": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-arm64",
|
"name": "@img/sharp-linux-arm64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Linux (glibc) ARM64",
|
"description": "Prebuilt sharp for use with Linux (glibc) 64-bit ARM",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linux-arm64": "0.0.1"
|
"@img/sharp-libvips-linux-arm64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
47
npm/linux-s390x/package.json
Normal file
47
npm/linux-s390x/package.json
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "@img/sharp-linux-s390x",
|
||||||
|
"version": "0.33.0-alpha.10",
|
||||||
|
"description": "Prebuilt sharp for use with Linux (glibc) s390x",
|
||||||
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/lovell/sharp.git",
|
||||||
|
"directory": "npm/linux-s390x"
|
||||||
|
},
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"preferUnplugged": true,
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-s390x": "0.0.3"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"type": "commonjs",
|
||||||
|
"exports": {
|
||||||
|
"./sharp.node": "./lib/sharp-linux-s390x.node",
|
||||||
|
"./package": "./package.json"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||||
|
"npm": ">=9.6.5",
|
||||||
|
"yarn": ">=3.2.0",
|
||||||
|
"pnpm": ">=7.1.0",
|
||||||
|
"glibc": ">=2.28"
|
||||||
|
},
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-x64",
|
"name": "@img/sharp-linux-x64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Linux (glibc) x64",
|
"description": "Prebuilt sharp for use with Linux (glibc) x64",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linux-x64": "0.0.1"
|
"@img/sharp-libvips-linux-x64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linuxmusl-arm64",
|
"name": "@img/sharp-linuxmusl-arm64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Linux (musl) ARM64",
|
"description": "Prebuilt sharp for use with Linux (musl) 64-bit ARM",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": "0.0.1"
|
"@img/sharp-libvips-linuxmusl-arm64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linuxmusl-x64",
|
"name": "@img/sharp-linuxmusl-x64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Linux (musl) x64",
|
"description": "Prebuilt sharp for use with Linux (musl) x64",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linuxmusl-x64": "0.0.1"
|
"@img/sharp-libvips-linuxmusl-x64": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp",
|
"name": "@img/sharp",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"darwin-x64",
|
|
||||||
"darwin-arm64",
|
"darwin-arm64",
|
||||||
|
"darwin-x64",
|
||||||
"linux-arm",
|
"linux-arm",
|
||||||
"linux-arm64",
|
"linux-arm64",
|
||||||
|
"linux-s390x",
|
||||||
|
"linux-x64",
|
||||||
"linuxmusl-arm64",
|
"linuxmusl-arm64",
|
||||||
"linuxmusl-x64",
|
"linuxmusl-x64",
|
||||||
"linux-x64",
|
|
||||||
"win32-ia32",
|
"win32-ia32",
|
||||||
"win32-x64"
|
"win32-x64"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-win32-ia32",
|
"name": "@img/sharp-win32-ia32",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Windows x86 (32-bit)",
|
"description": "Prebuilt sharp for use with Windows x86 (32-bit)",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-win32-x64",
|
"name": "@img/sharp-win32-x64",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"description": "Prebuilt sharp for use with Windows x64",
|
"description": "Prebuilt sharp for use with Windows x64",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
|
|||||||
47
package.json
47
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
||||||
"version": "0.33.0-alpha.9",
|
"version": "0.33.0-alpha.10",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://github.com/lovell/sharp",
|
"homepage": "https://github.com/lovell/sharp",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -86,7 +86,8 @@
|
|||||||
"Ankur Parihar <ankur.github@gmail.com>",
|
"Ankur Parihar <ankur.github@gmail.com>",
|
||||||
"Brahim Ait elhaj <brahima@gmail.com>",
|
"Brahim Ait elhaj <brahima@gmail.com>",
|
||||||
"Mart Jansink <m.jansink@gmail.com>",
|
"Mart Jansink <m.jansink@gmail.com>",
|
||||||
"Lachlan Newman <lachnewman007@gmail.com>"
|
"Lachlan Newman <lachnewman007@gmail.com>",
|
||||||
|
"Dennis Beatty <dennis@dcbeatty.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "node install/check",
|
"install": "node install/check",
|
||||||
@@ -139,27 +140,29 @@
|
|||||||
"semver": "^7.5.4"
|
"semver": "^7.5.4"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-darwin-arm64": "0.33.0-alpha.9",
|
"@img/sharp-darwin-arm64": "0.33.0-alpha.10",
|
||||||
"@img/sharp-darwin-x64": "0.33.0-alpha.9",
|
"@img/sharp-darwin-x64": "0.33.0-alpha.10",
|
||||||
"@img/sharp-libvips-darwin-arm64": "0.0.1",
|
"@img/sharp-libvips-darwin-arm64": "0.0.3",
|
||||||
"@img/sharp-libvips-darwin-x64": "0.0.1",
|
"@img/sharp-libvips-darwin-x64": "0.0.3",
|
||||||
"@img/sharp-libvips-linux-arm": "0.0.1",
|
"@img/sharp-libvips-linux-arm": "0.0.3",
|
||||||
"@img/sharp-libvips-linux-arm64": "0.0.1",
|
"@img/sharp-libvips-linux-arm64": "0.0.3",
|
||||||
"@img/sharp-libvips-linux-x64": "0.0.1",
|
"@img/sharp-libvips-linux-s390x": "0.0.3",
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": "0.0.1",
|
"@img/sharp-libvips-linux-x64": "0.0.3",
|
||||||
"@img/sharp-libvips-linuxmusl-x64": "0.0.1",
|
"@img/sharp-libvips-linuxmusl-arm64": "0.0.3",
|
||||||
"@img/sharp-linux-arm": "0.33.0-alpha.9",
|
"@img/sharp-libvips-linuxmusl-x64": "0.0.3",
|
||||||
"@img/sharp-linux-arm64": "0.33.0-alpha.9",
|
"@img/sharp-linux-arm": "0.33.0-alpha.10",
|
||||||
"@img/sharp-linux-x64": "0.33.0-alpha.9",
|
"@img/sharp-linux-arm64": "0.33.0-alpha.10",
|
||||||
"@img/sharp-linuxmusl-arm64": "0.33.0-alpha.9",
|
"@img/sharp-linux-s390x": "0.33.0-alpha.10",
|
||||||
"@img/sharp-linuxmusl-x64": "0.33.0-alpha.9",
|
"@img/sharp-linux-x64": "0.33.0-alpha.10",
|
||||||
"@img/sharp-win32-ia32": "0.33.0-alpha.9",
|
"@img/sharp-linuxmusl-arm64": "0.33.0-alpha.10",
|
||||||
"@img/sharp-win32-x64": "0.33.0-alpha.9"
|
"@img/sharp-linuxmusl-x64": "0.33.0-alpha.10",
|
||||||
|
"@img/sharp-win32-ia32": "0.33.0-alpha.10",
|
||||||
|
"@img/sharp-win32-x64": "0.33.0-alpha.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@img/sharp-libvips-dev": "0.0.1",
|
"@img/sharp-libvips-dev": "0.0.3",
|
||||||
"@img/sharp-libvips-win32-ia32": "0.0.1",
|
"@img/sharp-libvips-win32-ia32": "0.0.3",
|
||||||
"@img/sharp-libvips-win32-x64": "0.0.1",
|
"@img/sharp-libvips-win32-x64": "0.0.3",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"async": "^3.2.4",
|
"async": "^3.2.4",
|
||||||
"cc": "^3.0.1",
|
"cc": "^3.0.1",
|
||||||
@@ -179,7 +182,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||||
"libvips": ">=8.14.5"
|
"libvips": ">=8.15.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/libvips"
|
"url": "https://opencollective.com/libvips"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
'variables': {
|
'variables': {
|
||||||
'vips_version': '<!(node -p "require(\'../lib/libvips\').minimumLibvipsVersion")',
|
'vips_version': '<!(node -p "require(\'../lib/libvips\').minimumLibvipsVersion")',
|
||||||
'platform_and_arch': '<!(node -p "require(\'../lib/libvips\').buildPlatformArch()")',
|
'platform_and_arch': '<!(node -p "require(\'../lib/libvips\').buildPlatformArch()")',
|
||||||
|
'sharp_libvips_version': '<!(node -p "require(\'../package.json\').optionalDependencies[\'@img/sharp-libvips-<(platform_and_arch)\']")',
|
||||||
'sharp_libvips_include_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsIncludeDir()")',
|
'sharp_libvips_include_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsIncludeDir()")',
|
||||||
'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
|
'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
|
||||||
'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
|
'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
|
||||||
@@ -32,11 +33,11 @@
|
|||||||
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
'library_dirs': [
|
||||||
|
'<(sharp_libvips_lib_dir)'
|
||||||
|
],
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips.lib',
|
'libvips.lib'
|
||||||
'libglib-2.0.lib',
|
|
||||||
'libgobject-2.0.lib'
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'configurations': {
|
'configurations': {
|
||||||
@@ -129,6 +130,9 @@
|
|||||||
'<(sharp_libvips_include_dir)/glib-2.0',
|
'<(sharp_libvips_include_dir)/glib-2.0',
|
||||||
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||||
],
|
],
|
||||||
|
'library_dirs': [
|
||||||
|
'<(sharp_libvips_lib_dir)'
|
||||||
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
'defines': [
|
'defines': [
|
||||||
@@ -136,19 +140,13 @@
|
|||||||
'_FILE_OFFSET_BITS=64'
|
'_FILE_OFFSET_BITS=64'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips.lib',
|
'libvips.lib'
|
||||||
'libglib-2.0.lib',
|
|
||||||
'libgobject-2.0.lib'
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
['OS == "mac"', {
|
['OS == "mac"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': [
|
|
||||||
'<(sharp_libvips_lib_dir)'
|
|
||||||
],
|
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips-cpp.42.dylib'
|
'libvips-cpp.42.dylib'
|
||||||
]
|
]
|
||||||
@@ -157,6 +155,7 @@
|
|||||||
'OTHER_LDFLAGS': [
|
'OTHER_LDFLAGS': [
|
||||||
# Ensure runtime linking is relative to sharp.node
|
# Ensure runtime linking is relative to sharp.node
|
||||||
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
|
'-Wl,-rpath,\'@loader_path/../../../<(sharp_libvips_version)/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
'-Wl,-rpath,\'@loader_path/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
'-Wl,-rpath,\'@loader_path/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
'-Wl,-rpath,\'@loader_path/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
'-Wl,-rpath,\'@loader_path/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
||||||
]
|
]
|
||||||
@@ -167,9 +166,6 @@
|
|||||||
'_GLIBCXX_USE_CXX11_ABI=1'
|
'_GLIBCXX_USE_CXX11_ABI=1'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': [
|
|
||||||
'<(sharp_libvips_lib_dir)'
|
|
||||||
],
|
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'-l:libvips-cpp.so.42'
|
'-l:libvips-cpp.so.42'
|
||||||
],
|
],
|
||||||
@@ -178,6 +174,7 @@
|
|||||||
'-Wl,-s',
|
'-Wl,-s',
|
||||||
'-Wl,--disable-new-dtags',
|
'-Wl,--disable-new-dtags',
|
||||||
'-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
'-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
|
'-Wl,-rpath=\'$$ORIGIN/../../../<(sharp_libvips_version)/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
'-Wl,-rpath=\'$$ORIGIN/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
'-Wl,-rpath=\'$$ORIGIN/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||||
'-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
'-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
|
||||||
]
|
]
|
||||||
@@ -256,9 +253,7 @@
|
|||||||
'copies': [{
|
'copies': [{
|
||||||
'destination': 'build/Release',
|
'destination': 'build/Release',
|
||||||
'files': [
|
'files': [
|
||||||
'<(sharp_libvips_lib_dir)/libvips-42.dll',
|
'<(sharp_libvips_lib_dir)/libvips-42.dll'
|
||||||
'<(sharp_libvips_lib_dir)/libglib-2.0-0.dll',
|
|
||||||
'<(sharp_libvips_lib_dir)/libgobject-2.0-0.dll'
|
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
// Verify platform and compiler compatibility
|
// Verify platform and compiler compatibility
|
||||||
|
|
||||||
#if (VIPS_MAJOR_VERSION < 8) || \
|
#if (VIPS_MAJOR_VERSION < 8) || \
|
||||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 14) || \
|
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 15) || \
|
||||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 14 && VIPS_MICRO_VERSION < 5)
|
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 0)
|
||||||
#error "libvips version 8.14.5+ is required - please see https://sharp.pixelplumbing.com/install"
|
#error "libvips version 8.15.0+ is required - please see https://sharp.pixelplumbing.com/install"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
// Handle warnings
|
// Handle warnings
|
||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,9 +246,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
|
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
|
||||||
baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
||||||
}
|
}
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
Callback().Call(Receiver().Value(), { env.Null(), info });
|
||||||
} else {
|
} else {
|
||||||
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
||||||
}
|
}
|
||||||
|
|
||||||
delete baton->input;
|
delete baton->input;
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ namespace sharp {
|
|||||||
return image.conv(blur);
|
return image.conv(blur);
|
||||||
} else {
|
} else {
|
||||||
// Slower, accurate Gaussian blur
|
// Slower, accurate Gaussian blur
|
||||||
return image.gaussblur(sigma);
|
return StaySequential(image, VIPS_ACCESS_SEQUENTIAL).gaussblur(sigma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ namespace sharp {
|
|||||||
/*
|
/*
|
||||||
Trim an image
|
Trim an image
|
||||||
*/
|
*/
|
||||||
VImage Trim(VImage image, std::vector<double> background, double threshold) {
|
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt) {
|
||||||
if (image.width() < 3 && image.height() < 3) {
|
if (image.width() < 3 && image.height() < 3) {
|
||||||
throw VError("Image to trim must be at least 3x3 pixels");
|
throw VError("Image to trim must be at least 3x3 pixels");
|
||||||
}
|
}
|
||||||
@@ -287,6 +287,7 @@ namespace sharp {
|
|||||||
int left, top, width, height;
|
int left, top, width, height;
|
||||||
left = image.find_trim(&top, &width, &height, VImage::option()
|
left = image.find_trim(&top, &width, &height, VImage::option()
|
||||||
->set("background", background)
|
->set("background", background)
|
||||||
|
->set("line_art", lineArt)
|
||||||
->set("threshold", threshold));
|
->set("threshold", threshold));
|
||||||
if (HasAlpha(image)) {
|
if (HasAlpha(image)) {
|
||||||
// Search alpha channel (A)
|
// Search alpha channel (A)
|
||||||
@@ -294,6 +295,7 @@ namespace sharp {
|
|||||||
VImage alpha = image[image.bands() - 1];
|
VImage alpha = image[image.bands() - 1];
|
||||||
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
|
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
|
||||||
->set("background", backgroundAlpha)
|
->set("background", backgroundAlpha)
|
||||||
|
->set("line_art", lineArt)
|
||||||
->set("threshold", threshold));
|
->set("threshold", threshold));
|
||||||
if (widthA > 0 && heightA > 0) {
|
if (widthA > 0 && heightA > 0) {
|
||||||
if (width > 0 && height > 0) {
|
if (width > 0 && height > 0) {
|
||||||
@@ -370,6 +372,7 @@ namespace sharp {
|
|||||||
pages.reserve(nPages);
|
pages.reserve(nPages);
|
||||||
|
|
||||||
// Split the image into cropped frames
|
// Split the image into cropped frames
|
||||||
|
image = StaySequential(image, VIPS_ACCESS_SEQUENTIAL);
|
||||||
for (int i = 0; i < nPages; i++) {
|
for (int i = 0; i < nPages; i++) {
|
||||||
pages.push_back(
|
pages.push_back(
|
||||||
image.extract_area(left, *pageHeight * i + top, width, height));
|
image.extract_area(left, *pageHeight * i + top, width, height));
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace sharp {
|
|||||||
/*
|
/*
|
||||||
Trim an image
|
Trim an image
|
||||||
*/
|
*/
|
||||||
VImage Trim(VImage image, std::vector<double> background, double const threshold);
|
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Linear adjustment (a * in + b)
|
* Linear adjustment (a * in + b)
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trim
|
// Trim
|
||||||
if (baton->trimThreshold > 0.0) {
|
if (baton->trimThreshold >= 0.0) {
|
||||||
MultiPageUnsupported(nPages, "Trim");
|
MultiPageUnsupported(nPages, "Trim");
|
||||||
image = sharp::StaySequential(image, access);
|
image = sharp::StaySequential(image, access);
|
||||||
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold);
|
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt);
|
||||||
baton->trimOffsetLeft = image.xoffset();
|
baton->trimOffsetLeft = image.xoffset();
|
||||||
baton->trimOffsetTop = image.yoffset();
|
baton->trimOffsetTop = image.yoffset();
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
// - trimming or pre-resize extract isn't required;
|
// - trimming or pre-resize extract isn't required;
|
||||||
// - input colourspace is not specified;
|
// - input colourspace is not specified;
|
||||||
bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0) &&
|
bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0) &&
|
||||||
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0 &&
|
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold < 0.0 &&
|
||||||
baton->colourspaceInput == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
|
baton->colourspaceInput == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
|
||||||
|
|
||||||
if (shouldPreShrink) {
|
if (shouldPreShrink) {
|
||||||
@@ -485,9 +485,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
image = sharp::StaySequential(image, access);
|
image = sharp::StaySequential(image, access);
|
||||||
image = image.smartcrop(baton->width, baton->height, VImage::option()
|
image = image.smartcrop(baton->width, baton->height, VImage::option()
|
||||||
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
||||||
#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 15)
|
|
||||||
->set("premultiplied", shouldPremultiplyAlpha)
|
->set("premultiplied", shouldPremultiplyAlpha)
|
||||||
#endif
|
|
||||||
->set("attention_x", &attention_x)
|
->set("attention_x", &attention_x)
|
||||||
->set("attention_y", &attention_y));
|
->set("attention_y", &attention_y));
|
||||||
baton->hasCropOffset = true;
|
baton->hasCropOffset = true;
|
||||||
@@ -940,6 +938,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
->set("Q", baton->tiffQuality)
|
->set("Q", baton->tiffQuality)
|
||||||
->set("bitdepth", baton->tiffBitdepth)
|
->set("bitdepth", baton->tiffBitdepth)
|
||||||
->set("compression", baton->tiffCompression)
|
->set("compression", baton->tiffCompression)
|
||||||
|
->set("miniswhite", baton->tiffMiniswhite)
|
||||||
->set("predictor", baton->tiffPredictor)
|
->set("predictor", baton->tiffPredictor)
|
||||||
->set("pyramid", baton->tiffPyramid)
|
->set("pyramid", baton->tiffPyramid)
|
||||||
->set("tile", baton->tiffTile)
|
->set("tile", baton->tiffTile)
|
||||||
@@ -1136,6 +1135,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
->set("Q", baton->tiffQuality)
|
->set("Q", baton->tiffQuality)
|
||||||
->set("bitdepth", baton->tiffBitdepth)
|
->set("bitdepth", baton->tiffBitdepth)
|
||||||
->set("compression", baton->tiffCompression)
|
->set("compression", baton->tiffCompression)
|
||||||
|
->set("miniswhite", baton->tiffMiniswhite)
|
||||||
->set("predictor", baton->tiffPredictor)
|
->set("predictor", baton->tiffPredictor)
|
||||||
->set("pyramid", baton->tiffPyramid)
|
->set("pyramid", baton->tiffPyramid)
|
||||||
->set("tile", baton->tiffTile)
|
->set("tile", baton->tiffTile)
|
||||||
@@ -1215,7 +1215,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
// Handle warnings
|
// Handle warnings
|
||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1248,11 +1248,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
info.Set("attentionX", static_cast<int32_t>(baton->attentionX));
|
info.Set("attentionX", static_cast<int32_t>(baton->attentionX));
|
||||||
info.Set("attentionY", static_cast<int32_t>(baton->attentionY));
|
info.Set("attentionY", static_cast<int32_t>(baton->attentionY));
|
||||||
}
|
}
|
||||||
if (baton->trimThreshold > 0.0) {
|
if (baton->trimThreshold >= 0.0) {
|
||||||
info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
|
info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
|
||||||
info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
|
info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baton->input->textAutofitDpi) {
|
if (baton->input->textAutofitDpi) {
|
||||||
info.Set("textAutofitDpi", static_cast<uint32_t>(baton->input->textAutofitDpi));
|
info.Set("textAutofitDpi", static_cast<uint32_t>(baton->input->textAutofitDpi));
|
||||||
}
|
}
|
||||||
@@ -1263,17 +1262,17 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
// Pass ownership of output data to Buffer instance
|
// Pass ownership of output data to Buffer instance
|
||||||
Napi::Buffer<char> data = Napi::Buffer<char>::NewOrCopy(env, static_cast<char*>(baton->bufferOut),
|
Napi::Buffer<char> data = Napi::Buffer<char>::NewOrCopy(env, static_cast<char*>(baton->bufferOut),
|
||||||
baton->bufferOutLength, sharp::FreeCallback);
|
baton->bufferOutLength, sharp::FreeCallback);
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
|
Callback().Call(Receiver().Value(), { env.Null(), data, info });
|
||||||
} else {
|
} else {
|
||||||
// Add file size to info
|
// Add file size to info
|
||||||
struct STAT64_STRUCT st;
|
struct STAT64_STRUCT st;
|
||||||
if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
|
if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
|
||||||
info.Set("size", static_cast<uint32_t>(st.st_size));
|
info.Set("size", static_cast<uint32_t>(st.st_size));
|
||||||
}
|
}
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
Callback().Call(Receiver().Value(), { env.Null(), info });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete baton
|
// Delete baton
|
||||||
@@ -1291,7 +1290,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
// Decrement processing task counter
|
// Decrement processing task counter
|
||||||
sharp::counterProcess--;
|
sharp::counterProcess--;
|
||||||
Napi::Number queueLength = Napi::Number::New(env, static_cast<int>(sharp::counterQueue));
|
Napi::Number queueLength = Napi::Number::New(env, static_cast<int>(sharp::counterQueue));
|
||||||
queueListener.MakeCallback(Receiver().Value(), { queueLength });
|
queueListener.Call(Receiver().Value(), { queueLength });
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1519,6 +1518,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
|
baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
|
||||||
baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground");
|
baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground");
|
||||||
baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
|
baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
|
||||||
|
baton->trimLineArt = sharp::AttrAsBool(options, "trimLineArt");
|
||||||
baton->gamma = sharp::AttrAsDouble(options, "gamma");
|
baton->gamma = sharp::AttrAsDouble(options, "gamma");
|
||||||
baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
|
baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
|
||||||
baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA");
|
baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA");
|
||||||
@@ -1647,6 +1647,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
|
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
|
||||||
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
|
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
|
||||||
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
|
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
|
||||||
|
baton->tiffMiniswhite = sharp::AttrAsBool(options, "tiffMiniswhite");
|
||||||
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
|
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
|
||||||
baton->tiffTile = sharp::AttrAsBool(options, "tiffTile");
|
baton->tiffTile = sharp::AttrAsBool(options, "tiffTile");
|
||||||
baton->tiffTileWidth = sharp::AttrAsUint32(options, "tiffTileWidth");
|
baton->tiffTileWidth = sharp::AttrAsUint32(options, "tiffTileWidth");
|
||||||
@@ -1708,7 +1709,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
|
|
||||||
// Increment queued task counter
|
// Increment queued task counter
|
||||||
Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<int>(++sharp::counterQueue));
|
Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<int>(++sharp::counterQueue));
|
||||||
queueListener.MakeCallback(info.This(), { queueLength });
|
queueListener.Call(info.This(), { queueLength });
|
||||||
|
|
||||||
return info.Env().Undefined();
|
return info.Env().Undefined();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ struct PipelineBaton {
|
|||||||
bool thresholdGrayscale;
|
bool thresholdGrayscale;
|
||||||
std::vector<double> trimBackground;
|
std::vector<double> trimBackground;
|
||||||
double trimThreshold;
|
double trimThreshold;
|
||||||
|
bool trimLineArt;
|
||||||
int trimOffsetLeft;
|
int trimOffsetLeft;
|
||||||
int trimOffsetTop;
|
int trimOffsetTop;
|
||||||
std::vector<double> linearA;
|
std::vector<double> linearA;
|
||||||
@@ -169,6 +170,7 @@ struct PipelineBaton {
|
|||||||
VipsForeignTiffPredictor tiffPredictor;
|
VipsForeignTiffPredictor tiffPredictor;
|
||||||
bool tiffPyramid;
|
bool tiffPyramid;
|
||||||
int tiffBitdepth;
|
int tiffBitdepth;
|
||||||
|
bool tiffMiniswhite;
|
||||||
bool tiffTile;
|
bool tiffTile;
|
||||||
int tiffTileHeight;
|
int tiffTileHeight;
|
||||||
int tiffTileWidth;
|
int tiffTileWidth;
|
||||||
@@ -259,7 +261,8 @@ struct PipelineBaton {
|
|||||||
threshold(0),
|
threshold(0),
|
||||||
thresholdGrayscale(true),
|
thresholdGrayscale(true),
|
||||||
trimBackground{},
|
trimBackground{},
|
||||||
trimThreshold(0.0),
|
trimThreshold(-1.0),
|
||||||
|
trimLineArt(false),
|
||||||
trimOffsetLeft(0),
|
trimOffsetLeft(0),
|
||||||
trimOffsetTop(0),
|
trimOffsetTop(0),
|
||||||
linearA{},
|
linearA{},
|
||||||
@@ -335,6 +338,7 @@ struct PipelineBaton {
|
|||||||
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
|
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
|
||||||
tiffPyramid(false),
|
tiffPyramid(false),
|
||||||
tiffBitdepth(8),
|
tiffBitdepth(8),
|
||||||
|
tiffMiniswhite(false),
|
||||||
tiffTile(false),
|
tiffTile(false),
|
||||||
tiffTileHeight(256),
|
tiffTileHeight(256),
|
||||||
tiffTileWidth(256),
|
tiffTileWidth(256),
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
|||||||
// Handle warnings
|
// Handle warnings
|
||||||
std::string warning = sharp::VipsWarningPop();
|
std::string warning = sharp::VipsWarningPop();
|
||||||
while (!warning.empty()) {
|
while (!warning.empty()) {
|
||||||
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
|
||||||
warning = sharp::VipsWarningPop();
|
warning = sharp::VipsWarningPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,9 +141,9 @@ class StatsWorker : public Napi::AsyncWorker {
|
|||||||
dominant.Set("g", baton->dominantGreen);
|
dominant.Set("g", baton->dominantGreen);
|
||||||
dominant.Set("b", baton->dominantBlue);
|
dominant.Set("b", baton->dominantBlue);
|
||||||
info.Set("dominant", dominant);
|
info.Set("dominant", dominant);
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
Callback().Call(Receiver().Value(), { env.Null(), info });
|
||||||
} else {
|
} else {
|
||||||
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
||||||
}
|
}
|
||||||
|
|
||||||
delete baton->input;
|
delete baton->input;
|
||||||
|
|||||||
@@ -572,8 +572,8 @@ const nohalo: string = sharp.interpolators.nohalo;
|
|||||||
const vertexSplitQuadraticBasisSpline: string = sharp.interpolators.vertexSplitQuadraticBasisSpline;
|
const vertexSplitQuadraticBasisSpline: string = sharp.interpolators.vertexSplitQuadraticBasisSpline;
|
||||||
|
|
||||||
// Triming
|
// Triming
|
||||||
sharp(input).trim('#000').toBuffer();
|
sharp(input).trim({ background: '#000' }).toBuffer();
|
||||||
sharp(input).trim(10).toBuffer();
|
sharp(input).trim({ threshold: 10, lineArt: true }).toBuffer();
|
||||||
sharp(input).trim({ background: '#bf1942', threshold: 30 }).toBuffer();
|
sharp(input).trim({ background: '#bf1942', threshold: 30 }).toBuffer();
|
||||||
|
|
||||||
// Text input
|
// Text input
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ describe('composite', () => {
|
|||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(300, 300)
|
.resize(300, 300)
|
||||||
.composite([{
|
.composite([{
|
||||||
input: Buffer.from('<svg width="200" height="200"><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>'),
|
input: Buffer.from('<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>'),
|
||||||
density: 96,
|
density: 96,
|
||||||
blend: 'dest-in',
|
blend: 'dest-in',
|
||||||
cutout: true
|
cutout: true
|
||||||
|
|||||||
@@ -6,43 +6,44 @@
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
const sharp = require('../../');
|
const sharp = require('../../');
|
||||||
const fixtures = require('../fixtures');
|
|
||||||
|
|
||||||
describe('Median filter', () => {
|
const row = [0, 3, 15, 63, 127, 255];
|
||||||
it('1x1 window', async () => {
|
const input = Buffer.from(Array.from(row, () => row).flat());
|
||||||
const [r, g, b] = await sharp(fixtures.inputSvgSmallViewBox)
|
const raw = {
|
||||||
.median(1)
|
width: 6,
|
||||||
|
height: 6,
|
||||||
|
channels: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Median filter', function () {
|
||||||
|
it('default window (3x3)', async () => {
|
||||||
|
const data = await sharp(input, { raw })
|
||||||
|
.median()
|
||||||
|
.toColourspace('b-w')
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
assert.deepStrictEqual({ r: 0, g: 0, b: 0 }, { r, g, b });
|
assert.deepStrictEqual(data.subarray(0, 6), Buffer.from(row));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('3x3 window', async () => {
|
it('3x3 window', async () => {
|
||||||
const [r, g, b] = await sharp(fixtures.inputSvgSmallViewBox)
|
const data = await sharp(input, { raw })
|
||||||
.median(3)
|
.median(3)
|
||||||
|
.toColourspace('b-w')
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
assert.deepStrictEqual({ r: 255, g: 0, b: 127 }, { r, g, b });
|
assert.deepStrictEqual(data.subarray(0, 6), Buffer.from(row));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('7x7 window', async () => {
|
it('5x5 window', async () => {
|
||||||
const [r, g, b] = await sharp(fixtures.inputSvgSmallViewBox)
|
const data = await sharp(input, { raw })
|
||||||
.median(7)
|
.median(5)
|
||||||
|
.toColourspace('b-w')
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
assert.deepStrictEqual({ r: 255, g: 19, b: 146 }, { r, g, b });
|
assert.deepStrictEqual(data.subarray(0, 6), Buffer.from([0, 3, 15, 15, 63, 127]));
|
||||||
});
|
|
||||||
|
|
||||||
it('default window (3x3)', async () => {
|
|
||||||
const [r, g, b] = await sharp(fixtures.inputSvgSmallViewBox)
|
|
||||||
.median()
|
|
||||||
.raw()
|
|
||||||
.toBuffer();
|
|
||||||
|
|
||||||
assert.deepStrictEqual({ r: 255, g: 0, b: 127 }, { r, g, b });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invalid radius', () => {
|
it('invalid radius', () => {
|
||||||
|
|||||||
@@ -141,21 +141,21 @@ describe('SVG input', function () {
|
|||||||
|
|
||||||
it('Fails to render SVG larger than 32767x32767', () =>
|
it('Fails to render SVG larger than 32767x32767', () =>
|
||||||
assert.rejects(
|
assert.rejects(
|
||||||
() => sharp(Buffer.from('<svg width="32768" height="1" />')).toBuffer(),
|
() => sharp(Buffer.from('<svg xmlns="http://www.w3.org/2000/svg" width="32768" height="1" />')).toBuffer(),
|
||||||
/Input SVG image exceeds 32767x32767 pixel limit/
|
/Input SVG image exceeds 32767x32767 pixel limit/
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
it('Fails to render scaled SVG larger than 32767x32767', () =>
|
it('Fails to render scaled SVG larger than 32767x32767', () =>
|
||||||
assert.rejects(
|
assert.rejects(
|
||||||
() => sharp(Buffer.from('<svg width="32767" height="1" />')).resize(32768).toBuffer(),
|
() => sharp(Buffer.from('<svg xmlns="http://www.w3.org/2000/svg" width="32767" height="1" />')).resize(32768).toBuffer(),
|
||||||
/Input SVG image will exceed 32767x32767 pixel limit when scaled/
|
/Input SVG image will exceed 32767x32767 pixel limit when scaled/
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
it('Detects SVG passed as a string', () =>
|
it('Detects SVG passed as a string', () =>
|
||||||
assert.rejects(
|
assert.rejects(
|
||||||
() => sharp('<svg></svg>').toBuffer(),
|
() => sharp('<svg xmlns="http://www.w3.org/2000/svg"></svg>').toBuffer(),
|
||||||
/Input file is missing, did you mean/
|
/Input file is missing, did you mean/
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,17 +7,21 @@ const assert = require('assert');
|
|||||||
|
|
||||||
const sharp = require('../../');
|
const sharp = require('../../');
|
||||||
const fixtures = require('../fixtures');
|
const fixtures = require('../fixtures');
|
||||||
|
const { inRange } = require('../../lib/is');
|
||||||
|
|
||||||
describe('Text to image', function () {
|
describe('Text to image', function () {
|
||||||
this.retries(3);
|
this.retries(3);
|
||||||
|
|
||||||
it('text with default values', async () => {
|
it('text with default values', async function () {
|
||||||
const output = fixtures.path('output.text-default.png');
|
const output = fixtures.path('output.text-default.png');
|
||||||
const text = sharp({
|
const text = sharp({
|
||||||
text: {
|
text: {
|
||||||
text: 'Hello, world !'
|
text: 'Hello, world !'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
const info = await text.png().toFile(output);
|
const info = await text.png().toFile(output);
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
@@ -40,22 +44,23 @@ describe('Text to image', function () {
|
|||||||
|
|
||||||
it('text with width and height', function (done) {
|
it('text with width and height', function (done) {
|
||||||
const output = fixtures.path('output.text-width-height.png');
|
const output = fixtures.path('output.text-width-height.png');
|
||||||
const maxWidth = 500;
|
|
||||||
const maxHeight = 500;
|
|
||||||
const text = sharp({
|
const text = sharp({
|
||||||
text: {
|
text: {
|
||||||
text: 'Hello, world!',
|
text: 'Hello, world!',
|
||||||
width: maxWidth,
|
width: 500,
|
||||||
height: maxHeight
|
height: 400
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
text.toFile(output, function (err, info) {
|
text.toFile(output, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.ok(info.width <= maxWidth);
|
assert.ok(inRange(info.width, 450, 550), `Actual width ${info.width}`);
|
||||||
assert.ok(info.height <= maxHeight);
|
assert.ok(inRange(info.height, 300, 450), `Actual height ${info.height}`);
|
||||||
assert.ok(info.textAutofitDpi > 0);
|
assert.ok(inRange(info.textAutofitDpi, 900, 1200), `Actual textAutofitDpi ${info.textAutofitDpi}`);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -69,6 +74,9 @@ describe('Text to image', function () {
|
|||||||
dpi
|
dpi
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
text.toFile(output, function (err, info) {
|
text.toFile(output, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
@@ -90,6 +98,9 @@ describe('Text to image', function () {
|
|||||||
dpi
|
dpi
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
text.toFile(output, function (err, info) {
|
text.toFile(output, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
@@ -112,6 +123,9 @@ describe('Text to image', function () {
|
|||||||
font: 'sans 100'
|
font: 'sans 100'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
text.toFile(output, function (err, info) {
|
text.toFile(output, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
@@ -122,7 +136,7 @@ describe('Text to image', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('text with justify and composite', done => {
|
it('text with justify and composite', function (done) {
|
||||||
const output = fixtures.path('output.text-composite.png');
|
const output = fixtures.path('output.text-composite.png');
|
||||||
const width = 500;
|
const width = 500;
|
||||||
const dpi = 300;
|
const dpi = 300;
|
||||||
@@ -153,6 +167,9 @@ describe('Text to image', function () {
|
|||||||
left: 30,
|
left: 30,
|
||||||
top: 250
|
top: 250
|
||||||
}]);
|
}]);
|
||||||
|
if (!sharp.versions.pango) {
|
||||||
|
return this.skip();
|
||||||
|
}
|
||||||
text.toFile(output, function (err, info) {
|
text.toFile(output, function (err, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
|
|||||||
@@ -462,6 +462,18 @@ describe('TIFF', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('TIFF miniswhite true value does not throw error', function () {
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
sharp().tiff({ miniswhite: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Invalid TIFF miniswhite value throws error', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp().tiff({ miniswhite: 'true' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Invalid TIFF tile value throws error', function () {
|
it('Invalid TIFF tile value throws error', function () {
|
||||||
assert.throws(function () {
|
assert.throws(function () {
|
||||||
sharp().tiff({ tile: 'true' });
|
sharp().tiff({ tile: 'true' });
|
||||||
|
|||||||
@@ -741,28 +741,6 @@ describe('Tile', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Google layout with depth onepixel', function (done) {
|
|
||||||
const directory = fixtures.path('output.google_depth_onepixel.dzi');
|
|
||||||
fs.rm(directory, { recursive: true }, function () {
|
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.tile({
|
|
||||||
layout: 'google',
|
|
||||||
depth: 'onepixel',
|
|
||||||
size: 256
|
|
||||||
})
|
|
||||||
.toFile(directory, function (err, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('dz', info.format);
|
|
||||||
assert.strictEqual(2725, info.width);
|
|
||||||
assert.strictEqual(2225, info.height);
|
|
||||||
assert.strictEqual(3, info.channels);
|
|
||||||
assert.strictEqual('number', typeof info.size);
|
|
||||||
|
|
||||||
assertGoogleTiles(directory, 256, 13, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Google layout with depth onetile', function (done) {
|
it('Google layout with depth onetile', function (done) {
|
||||||
const directory = fixtures.path('output.google_depth_onetile.dzi');
|
const directory = fixtures.path('output.google_depth_onetile.dzi');
|
||||||
fs.rm(directory, { recursive: true }, function () {
|
fs.rm(directory, { recursive: true }, function () {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const fixtures = require('../fixtures');
|
|||||||
describe('Timeout', function () {
|
describe('Timeout', function () {
|
||||||
it('Will timeout after 1s when performing slow blur operation', () => assert.rejects(
|
it('Will timeout after 1s when performing slow blur operation', () => assert.rejects(
|
||||||
() => sharp(fixtures.inputJpg)
|
() => sharp(fixtures.inputJpg)
|
||||||
.blur(100)
|
.blur(200)
|
||||||
.timeout({ seconds: 1 })
|
.timeout({ seconds: 1 })
|
||||||
.toBuffer(),
|
.toBuffer(),
|
||||||
/timeout: [0-9]+% complete/
|
/timeout: [0-9]+% complete/
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ describe('Tint', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('tints rgb image with sepia tone', function (done) {
|
it('tints rgb image with sepia tone', function (done) {
|
||||||
const output = fixtures.path('output.tint-sepia.jpg');
|
const output = fixtures.path('output.tint-sepia-hex.jpg');
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240, { fastShrinkOnLoad: false })
|
.resize(320, 240, { fastShrinkOnLoad: false })
|
||||||
.tint('#704214')
|
.tint('#704214')
|
||||||
@@ -63,7 +63,7 @@ describe('Tint', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('tints rgb image with sepia tone with rgb colour', function (done) {
|
it('tints rgb image with sepia tone with rgb colour', function (done) {
|
||||||
const output = fixtures.path('output.tint-sepia.jpg');
|
const output = fixtures.path('output.tint-sepia-rgb.jpg');
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240, { fastShrinkOnLoad: false })
|
.resize(320, 240, { fastShrinkOnLoad: false })
|
||||||
.tint([112, 66, 20])
|
.tint([112, 66, 20])
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ describe('Trim borders', function () {
|
|||||||
it('16-bit PNG with alpha channel', function (done) {
|
it('16-bit PNG with alpha channel', function (done) {
|
||||||
sharp(fixtures.inputPngWithTransparency16bit)
|
sharp(fixtures.inputPngWithTransparency16bit)
|
||||||
.resize(32, 32)
|
.resize(32, 32)
|
||||||
.trim(20)
|
.trim({
|
||||||
|
threshold: 20
|
||||||
|
})
|
||||||
.toBuffer(function (err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, data.length > 0);
|
assert.strictEqual(true, data.length > 0);
|
||||||
@@ -96,7 +98,9 @@ describe('Trim borders', function () {
|
|||||||
.then(rotated30 =>
|
.then(rotated30 =>
|
||||||
sharp(rotated30)
|
sharp(rotated30)
|
||||||
.rotate(-30)
|
.rotate(-30)
|
||||||
.trim(128)
|
.trim({
|
||||||
|
threshold: 128
|
||||||
|
})
|
||||||
.toBuffer({ resolveWithObject: true })
|
.toBuffer({ resolveWithObject: true })
|
||||||
.then(({ info }) => {
|
.then(({ info }) => {
|
||||||
assert.strictEqual(20, info.width);
|
assert.strictEqual(20, info.width);
|
||||||
@@ -198,49 +202,26 @@ describe('Trim borders', function () {
|
|||||||
assert.strictEqual(trimOffsetLeft, 0);
|
assert.strictEqual(trimOffsetLeft, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Valid parameters', function () {
|
it('Works with line-art', async () => {
|
||||||
const expected = fixtures.expected('alpha-layer-1-fill-trim-resize.png');
|
const { info } = await sharp(fixtures.inputJpgOverlayLayer2)
|
||||||
Object.entries({
|
.trim({ lineArt: true })
|
||||||
'Background and threshold default': undefined,
|
.toBuffer({ resolveWithObject: true });
|
||||||
'Background string': '#00000000',
|
|
||||||
'Background option': {
|
assert.strictEqual(info.trimOffsetTop, -552);
|
||||||
background: '#00000000'
|
|
||||||
},
|
|
||||||
'Threshold number': 10,
|
|
||||||
'Threshold option': {
|
|
||||||
threshold: 10
|
|
||||||
}
|
|
||||||
}).forEach(function ([description, parameter]) {
|
|
||||||
it(description, function (done) {
|
|
||||||
sharp(fixtures.inputPngOverlayLayer1)
|
|
||||||
.resize(450, 322)
|
|
||||||
.trim(parameter)
|
|
||||||
.toBuffer(function (err, data, info) {
|
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual('png', info.format);
|
|
||||||
assert.strictEqual(450, info.width);
|
|
||||||
assert.strictEqual(322, info.height);
|
|
||||||
assert.strictEqual(-204, info.trimOffsetLeft);
|
|
||||||
assert.strictEqual(0, info.trimOffsetTop);
|
|
||||||
fixtures.assertSimilar(expected, data, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Invalid parameters', function () {
|
describe('Invalid parameters', function () {
|
||||||
Object.entries({
|
Object.entries({
|
||||||
'Invalid background string': 'fail',
|
'Invalid string': 'fail',
|
||||||
'Invalid background option': {
|
'Invalid background option': {
|
||||||
background: 'fail'
|
background: 'fail'
|
||||||
},
|
},
|
||||||
|
|
||||||
'Negative threshold number': -1,
|
|
||||||
'Negative threshold option': {
|
'Negative threshold option': {
|
||||||
threshold: -1
|
threshold: -1
|
||||||
},
|
},
|
||||||
|
'Invalid lineArt': {
|
||||||
Boolean: false
|
lineArt: 'fail'
|
||||||
|
}
|
||||||
}).forEach(function ([description, parameter]) {
|
}).forEach(function ([description, parameter]) {
|
||||||
it(description, function () {
|
it(description, function () {
|
||||||
assert.throws(function () {
|
assert.throws(function () {
|
||||||
@@ -253,7 +234,9 @@ describe('Trim borders', function () {
|
|||||||
describe('Specific background colour', function () {
|
describe('Specific background colour', function () {
|
||||||
it('Doesn\'t trim at all', async () => {
|
it('Doesn\'t trim at all', async () => {
|
||||||
const { info } = await sharp(fixtures.inputPngTrimSpecificColour)
|
const { info } = await sharp(fixtures.inputPngTrimSpecificColour)
|
||||||
.trim('yellow')
|
.trim({
|
||||||
|
background: 'yellow'
|
||||||
|
})
|
||||||
.toBuffer({ resolveWithObject: true });
|
.toBuffer({ resolveWithObject: true });
|
||||||
|
|
||||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||||
@@ -265,7 +248,9 @@ describe('Trim borders', function () {
|
|||||||
|
|
||||||
it('Only trims the bottom', async () => {
|
it('Only trims the bottom', async () => {
|
||||||
const { info } = await sharp(fixtures.inputPngTrimSpecificColour)
|
const { info } = await sharp(fixtures.inputPngTrimSpecificColour)
|
||||||
.trim('#21468B')
|
.trim({
|
||||||
|
background: '#21468B'
|
||||||
|
})
|
||||||
.toBuffer({ resolveWithObject: true });
|
.toBuffer({ resolveWithObject: true });
|
||||||
|
|
||||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||||
@@ -277,7 +262,9 @@ describe('Trim borders', function () {
|
|||||||
|
|
||||||
it('Only trims the bottom, in 16-bit', async () => {
|
it('Only trims the bottom, in 16-bit', async () => {
|
||||||
const { info } = await sharp(fixtures.inputPngTrimSpecificColour16bit)
|
const { info } = await sharp(fixtures.inputPngTrimSpecificColour16bit)
|
||||||
.trim('#21468B')
|
.trim({
|
||||||
|
background: '#21468B'
|
||||||
|
})
|
||||||
.toBuffer({ resolveWithObject: true });
|
.toBuffer({ resolveWithObject: true });
|
||||||
|
|
||||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||||
@@ -289,7 +276,9 @@ describe('Trim borders', function () {
|
|||||||
|
|
||||||
it('Only trims the bottom, including alpha', async () => {
|
it('Only trims the bottom, including alpha', async () => {
|
||||||
const { info } = await sharp(fixtures.inputPngTrimSpecificColourIncludeAlpha)
|
const { info } = await sharp(fixtures.inputPngTrimSpecificColourIncludeAlpha)
|
||||||
.trim('#21468B80')
|
.trim({
|
||||||
|
background: '#21468B80'
|
||||||
|
})
|
||||||
.toBuffer({ resolveWithObject: true });
|
.toBuffer({ resolveWithObject: true });
|
||||||
|
|
||||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||||
|
|||||||
Reference in New Issue
Block a user