Compare commits
55 Commits
v0.33.4
...
b7ff2645c4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7ff2645c4 | ||
|
|
79ac524262 | ||
|
|
92083ea64c | ||
|
|
82dc859a49 | ||
|
|
bee1fbaa34 | ||
|
|
eba82a8ba5 | ||
|
|
06b08bf10f | ||
|
|
7bdf419eb1 | ||
|
|
04e7f58cea | ||
|
|
3796dd8a87 | ||
|
|
8afec170ed | ||
|
|
3154af776e | ||
|
|
6480a94181 | ||
|
|
9582b5036f | ||
|
|
1533bf995a | ||
|
|
a53d7cb6bf | ||
|
|
b249357732 | ||
|
|
807d9241bd | ||
|
|
9bfaca2857 | ||
|
|
c26b77683a | ||
|
|
7ee54810d4 | ||
|
|
fc32e0bd3f | ||
|
|
0546e48467 | ||
|
|
ab65b7a0f1 | ||
|
|
2474bd4163 | ||
|
|
ff2e689d35 | ||
|
|
6327f13717 | ||
|
|
f1e69a218e | ||
|
|
3c14dbb21e | ||
|
|
82cebc31d0 | ||
|
|
ad36fa0605 | ||
|
|
de42667767 | ||
|
|
2eb03b0049 | ||
|
|
f7ed9b7fb6 | ||
|
|
7fbb988180 | ||
|
|
490210fc60 | ||
|
|
735fee74db | ||
|
|
67a5854b89 | ||
|
|
f128ebdbd4 | ||
|
|
2672de2480 | ||
|
|
67a4592756 | ||
|
|
10c6f474d9 | ||
|
|
d642108be2 | ||
|
|
c2a024101b | ||
|
|
2f0bbebfc9 | ||
|
|
60c5c5083d | ||
|
|
eab7dc1b49 | ||
|
|
5c7f37a0e0 | ||
|
|
ae06f46914 | ||
|
|
9c05ea8dd2 | ||
|
|
472aaf3311 | ||
|
|
56fae3eda1 | ||
|
|
cc96c21e42 | ||
|
|
1d344888ec | ||
|
|
bee235ee76 |
2
.github/ISSUE_TEMPLATE/installation.md
vendored
@@ -43,7 +43,7 @@ and try again before opening an issue.
|
|||||||
|
|
||||||
<!-- Please place an [x] in the relevant box to confirm. -->
|
<!-- Please place an [x] in the relevant box to confirm. -->
|
||||||
|
|
||||||
- [ ] I am using npm >= 9.6.5 with `--include=optional`
|
- [ ] I am using npm >= 10.1.0 with `--include=optional`
|
||||||
- [ ] I am using yarn >= 3.2.0
|
- [ ] I am using yarn >= 3.2.0
|
||||||
- [ ] I am using pnpm >= 7.1.0 with `--no-optional=false`
|
- [ ] I am using pnpm >= 7.1.0 with `--no-optional=false`
|
||||||
- [ ] I am using Deno
|
- [ ] I am using Deno
|
||||||
|
|||||||
59
.github/workflows/ci.yml
vendored
@@ -14,39 +14,54 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-24.04
|
||||||
container: rockylinux:8
|
container: rockylinux:8
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^18.17.0"
|
nodejs_version: "^18.17.0"
|
||||||
nodejs_version_major: 18
|
nodejs_version_major: 18
|
||||||
platform: linux-x64
|
platform: linux-x64
|
||||||
prebuild: true
|
prebuild: true
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-24.04
|
||||||
container: rockylinux:8
|
container: rockylinux:8
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^20.3.0"
|
nodejs_version: "^20.3.0"
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: linux-x64
|
platform: linux-x64
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-24.04
|
||||||
|
container: rockylinux:8
|
||||||
|
nodejs_arch: x64
|
||||||
|
nodejs_version: "^22.9.0"
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: linux-x64
|
||||||
|
- os: ubuntu-24.04
|
||||||
container: node:18-alpine3.17
|
container: node:18-alpine3.17
|
||||||
nodejs_version_major: 18
|
nodejs_version_major: 18
|
||||||
platform: linuxmusl-x64
|
platform: linuxmusl-x64
|
||||||
prebuild: true
|
prebuild: true
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-24.04
|
||||||
container: node:20-alpine3.18
|
container: node:20-alpine3.18
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: linuxmusl-x64
|
platform: linuxmusl-x64
|
||||||
- os: macos-11
|
- os: ubuntu-24.04
|
||||||
|
container: node:22-alpine3.20
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: linuxmusl-x64
|
||||||
|
- os: macos-13
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^18.17.0"
|
nodejs_version: "^18.17.0"
|
||||||
nodejs_version_major: 18
|
nodejs_version_major: 18
|
||||||
platform: darwin-x64
|
platform: darwin-x64
|
||||||
prebuild: true
|
prebuild: true
|
||||||
- os: macos-11
|
- os: macos-13
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^20.3.0"
|
nodejs_version: "^20.3.0"
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: darwin-x64
|
platform: darwin-x64
|
||||||
|
- os: macos-13
|
||||||
|
nodejs_arch: x64
|
||||||
|
nodejs_version: "^22.9.0"
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: darwin-x64
|
||||||
- os: macos-14
|
- os: macos-14
|
||||||
nodejs_arch: arm64
|
nodejs_arch: arm64
|
||||||
nodejs_version: "^18.17.0"
|
nodejs_version: "^18.17.0"
|
||||||
@@ -58,6 +73,11 @@ jobs:
|
|||||||
nodejs_version: "^20.3.0"
|
nodejs_version: "^20.3.0"
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: darwin-arm64
|
platform: darwin-arm64
|
||||||
|
- os: macos-14
|
||||||
|
nodejs_arch: arm64
|
||||||
|
nodejs_version: "^22.9.0"
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: darwin-arm64
|
||||||
- os: windows-2019
|
- os: windows-2019
|
||||||
nodejs_arch: x86
|
nodejs_arch: x86
|
||||||
nodejs_version: "18.18.2" # pinned to avoid 18.19.0 and npm 10
|
nodejs_version: "18.18.2" # pinned to avoid 18.19.0 and npm 10
|
||||||
@@ -69,6 +89,11 @@ jobs:
|
|||||||
nodejs_version: "^20.3.0"
|
nodejs_version: "^20.3.0"
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: win32-ia32
|
platform: win32-ia32
|
||||||
|
- os: windows-2019
|
||||||
|
nodejs_arch: x86
|
||||||
|
nodejs_version: "^22.9.0"
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: win32-ia32
|
||||||
- os: windows-2019
|
- os: windows-2019
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^18.17.0"
|
nodejs_version: "^18.17.0"
|
||||||
@@ -80,11 +105,16 @@ jobs:
|
|||||||
nodejs_version: "^20.3.0"
|
nodejs_version: "^20.3.0"
|
||||||
nodejs_version_major: 20
|
nodejs_version_major: 20
|
||||||
platform: win32-x64
|
platform: win32-x64
|
||||||
|
- os: windows-2019
|
||||||
|
nodejs_arch: x64
|
||||||
|
nodejs_version: "^22.9.0"
|
||||||
|
nodejs_version_major: 22
|
||||||
|
platform: win32-x64
|
||||||
steps:
|
steps:
|
||||||
- name: Dependencies (Rocky Linux glibc)
|
- name: Dependencies (Rocky Linux glibc)
|
||||||
if: contains(matrix.container, 'rockylinux')
|
if: contains(matrix.container, 'rockylinux')
|
||||||
run: |
|
run: |
|
||||||
dnf install -y gcc-toolset-11-gcc-c++ make git python3 fontconfig google-noto-sans-fonts
|
dnf install -y gcc-toolset-11-gcc-c++ make git python3.12 fontconfig google-noto-sans-fonts
|
||||||
echo "/opt/rh/gcc-toolset-11/root/usr/bin" >> $GITHUB_PATH
|
echo "/opt/rh/gcc-toolset-11/root/usr/bin" >> $GITHUB_PATH
|
||||||
- name: Dependencies (Linux musl)
|
- name: Dependencies (Linux musl)
|
||||||
if: contains(matrix.container, 'alpine')
|
if: contains(matrix.container, 'alpine')
|
||||||
@@ -125,13 +155,13 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
|
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- platform: linux-arm
|
- platform: linux-arm
|
||||||
distro: buster
|
distro: bullseye
|
||||||
run_on_arch: armv6
|
run_on_arch: armv6
|
||||||
nodejs_arch: armv6l
|
nodejs_arch: armv6l
|
||||||
nodejs_hostname: unofficial-builds.nodejs.org
|
nodejs_hostname: unofficial-builds.nodejs.org
|
||||||
@@ -144,6 +174,13 @@ jobs:
|
|||||||
nodejs_hostname: nodejs.org
|
nodejs_hostname: nodejs.org
|
||||||
nodejs_version: "18.17.0"
|
nodejs_version: "18.17.0"
|
||||||
nodejs_version_major: 18
|
nodejs_version_major: 18
|
||||||
|
- platform: linux-ppc64
|
||||||
|
distro: bullseye
|
||||||
|
run_on_arch: ppc64le
|
||||||
|
nodejs_arch: ppc64le
|
||||||
|
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
|
||||||
@@ -170,8 +207,8 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
name: wasm32 - prebuild
|
name: wasm32 - prebuild
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
container: "emscripten/emsdk:3.1.56"
|
container: "emscripten/emsdk:3.1.70"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|||||||
50
.github/workflows/npm.yml
vendored
@@ -16,49 +16,57 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: linux-x64-node-npm
|
- name: linux-x64-node-npm
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: npm
|
package-manager: npm
|
||||||
- name: linux-x64-node-pnpm
|
- name: linux-x64-node-pnpm
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: pnpm
|
package-manager: pnpm
|
||||||
- name: linux-x64-node-yarn
|
- name: linux-x64-node-yarn
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: yarn
|
package-manager: yarn
|
||||||
- name: linux-x64-node-yarn-pnp
|
- name: linux-x64-node-yarn-pnp
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: yarn-pnp
|
package-manager: yarn-pnp
|
||||||
|
- name: linux-x64-node-yarn-v1
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
runtime: node
|
||||||
|
package-manager: yarn-v1
|
||||||
- name: linux-x64-deno
|
- name: linux-x64-deno
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: deno
|
runtime: deno
|
||||||
- name: linux-x64-bun
|
- name: linux-x64-bun
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
runtime: bun
|
runtime: bun
|
||||||
|
|
||||||
- name: darwin-x64-node-npm
|
- name: darwin-x64-node-npm
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: npm
|
package-manager: npm
|
||||||
- name: darwin-x64-node-pnpm
|
- name: darwin-x64-node-pnpm
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: pnpm
|
package-manager: pnpm
|
||||||
- name: darwin-x64-node-yarn
|
- name: darwin-x64-node-yarn
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: yarn
|
package-manager: yarn
|
||||||
- name: darwin-x64-node-yarn-pnp
|
- name: darwin-x64-node-yarn-pnp
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: yarn-pnp
|
package-manager: yarn-pnp
|
||||||
|
- name: darwin-x64-node-yarn-v1
|
||||||
|
runs-on: macos-13
|
||||||
|
runtime: node
|
||||||
|
package-manager: yarn-v1
|
||||||
- name: darwin-x64-deno
|
- name: darwin-x64-deno
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: deno
|
runtime: deno
|
||||||
- name: darwin-x64-bun
|
- name: darwin-x64-bun
|
||||||
runs-on: macos-11
|
runs-on: macos-13
|
||||||
runtime: bun
|
runtime: bun
|
||||||
|
|
||||||
- name: win32-x64-node-npm
|
- name: win32-x64-node-npm
|
||||||
@@ -77,6 +85,10 @@ jobs:
|
|||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
runtime: node
|
runtime: node
|
||||||
package-manager: yarn-pnp
|
package-manager: yarn-pnp
|
||||||
|
- name: win32-x64-node-yarn-v1
|
||||||
|
runs-on: windows-2019
|
||||||
|
runtime: node
|
||||||
|
package-manager: yarn-v1
|
||||||
- name: win32-x64-deno
|
- name: win32-x64-deno
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
runtime: deno
|
runtime: deno
|
||||||
@@ -89,7 +101,7 @@ jobs:
|
|||||||
node-version: 20
|
node-version: 20
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
if: ${{ matrix.package-manager == 'pnpm' }}
|
if: ${{ matrix.package-manager == 'pnpm' }}
|
||||||
uses: pnpm/action-setup@v2
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: 8
|
||||||
- name: Install Deno
|
- name: Install Deno
|
||||||
@@ -99,13 +111,13 @@ jobs:
|
|||||||
deno-version: v1.x
|
deno-version: v1.x
|
||||||
- name: Install Bun
|
- name: Install Bun
|
||||||
if: ${{ matrix.runtime == 'bun' }}
|
if: ${{ matrix.runtime == 'bun' }}
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: oven-sh/setup-bun@v2
|
||||||
with:
|
with:
|
||||||
bun-version: latest
|
bun-version: latest
|
||||||
|
|
||||||
- name: Version
|
- name: Version
|
||||||
id: version
|
id: version
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
core.setOutput('semver', context.ref.replace('refs/tags/v',''))
|
core.setOutput('semver', context.ref.replace('refs/tags/v',''))
|
||||||
@@ -163,6 +175,14 @@ jobs:
|
|||||||
yarn install
|
yarn install
|
||||||
yarn node release.mjs
|
yarn node release.mjs
|
||||||
|
|
||||||
|
- name: Run with Node.js + yarn v1
|
||||||
|
if: ${{ matrix.package-manager == 'yarn-v1' }}
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
yarn set version classic
|
||||||
|
yarn install
|
||||||
|
node release.mjs
|
||||||
|
|
||||||
- name: Run with Deno
|
- name: Run with Deno
|
||||||
if: ${{ matrix.runtime == 'deno' }}
|
if: ${{ matrix.runtime == 'deno' }}
|
||||||
run: deno run --allow-read --allow-ffi release.mjs
|
run: deno run --allow-read --allow-ffi release.mjs
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ const output = await sharp(input)
|
|||||||
|
|
||||||
Convert to 8-bit greyscale; 256 shades of grey.
|
Convert to 8-bit greyscale; 256 shades of grey.
|
||||||
This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
|
This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
|
||||||
By default the output image will be web-friendly sRGB and contain three (identical) color channels.
|
By default the output image will be web-friendly sRGB and contain three (identical) colour channels.
|
||||||
This may be overridden by other sharp operations such as `toColourspace('b-w')`,
|
This may be overridden by other sharp operations such as `toColourspace('b-w')`,
|
||||||
which will produce an output image containing one color channel.
|
which will produce an output image containing one colour channel.
|
||||||
An alpha channel may be present, and will be unchanged by the operation.
|
An alpha channel may be present, and will be unchanged by the operation.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ Composite image(s) over the processed (resized, extracted etc.) image.
|
|||||||
The images to composite must be the same size or smaller than the processed image.
|
The images to composite must be the same size or smaller than the processed image.
|
||||||
If both `top` and `left` options are provided, they take precedence over `gravity`.
|
If both `top` and `left` options are provided, they take precedence over `gravity`.
|
||||||
|
|
||||||
Any resize, rotate or extract operations in the same processing pipeline
|
Other operations in the same processing pipeline (e.g. resize, rotate, flip,
|
||||||
will always be applied to the input image before composition.
|
flop, extract) will always be applied to the input image before composition.
|
||||||
|
|
||||||
The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
|
The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
|
||||||
`dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
|
`dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ where the overall height is the `pageHeight` multiplied by the number of `pages`
|
|||||||
| [options.page] | <code>number</code> | <code>0</code> | Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based. |
|
| [options.page] | <code>number</code> | <code>0</code> | Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based. |
|
||||||
| [options.subifd] | <code>number</code> | <code>-1</code> | subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. |
|
| [options.subifd] | <code>number</code> | <code>-1</code> | subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. |
|
||||||
| [options.level] | <code>number</code> | <code>0</code> | level to extract from a multi-level input (OpenSlide), zero based. |
|
| [options.level] | <code>number</code> | <code>0</code> | level to extract from a multi-level input (OpenSlide), zero based. |
|
||||||
|
| [options.pdfBackground] | <code>string</code> \| <code>Object</code> | | Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. |
|
||||||
| [options.animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. |
|
| [options.animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. |
|
||||||
| [options.raw] | <code>Object</code> | | describes raw pixel input image data. See `raw()` for pixel ordering. |
|
| [options.raw] | <code>Object</code> | | describes raw pixel input image data. See `raw()` for pixel ordering. |
|
||||||
| [options.raw.width] | <code>number</code> | | integral number of pixels wide. |
|
| [options.raw.width] | <code>number</code> | | integral number of pixels wide. |
|
||||||
|
|||||||
@@ -22,15 +22,16 @@ A `Promise` is returned when `callback` is not provided.
|
|||||||
- `density`: Number of pixels per inch (DPI), if present
|
- `density`: Number of pixels per inch (DPI), if present
|
||||||
- `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
- `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
||||||
- `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
- `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||||
|
- `isPalette`: Boolean indicating whether the image is palette-based (GIF, PNG).
|
||||||
|
- `bitsPerSample`: Number of bits per sample for each channel (GIF, PNG, HEIF).
|
||||||
- `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
- `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
||||||
- `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
- `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
||||||
- `paletteBitDepth`: Bit depth of palette-based image (GIF, PNG).
|
|
||||||
- `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
- `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
||||||
- `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
- `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
||||||
- `pagePrimary`: Number of the primary page in a HEIF image
|
- `pagePrimary`: Number of the primary page in a HEIF image
|
||||||
- `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
- `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
||||||
- `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
- `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
||||||
- `background`: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value
|
- `background`: Default background colour, if present, for PNG (bKGD) and GIF images
|
||||||
- `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
|
- `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
|
||||||
- `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
|
- `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
|
||||||
- `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
- `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
||||||
@@ -42,6 +43,7 @@ A `Promise` is returned when `callback` is not provided.
|
|||||||
- `xmp`: Buffer containing raw XMP data, if present
|
- `xmp`: Buffer containing raw XMP data, if present
|
||||||
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||||
- `formatMagick`: String containing format for images loaded via *magick
|
- `formatMagick`: String containing format for images loaded via *magick
|
||||||
|
- `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ const output = await sharp(input).flop().toBuffer();
|
|||||||
Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
||||||
|
|
||||||
You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
||||||
By default, new pixels are filled with a black background. You can provide a background color with the `background` option.
|
By default, new pixels are filled with a black background. You can provide a background colour with the `background` option.
|
||||||
A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
||||||
|
|
||||||
In the case of a 2x2 matrix, the transform is:
|
In the case of a 2x2 matrix, the transform is:
|
||||||
@@ -231,7 +231,7 @@ const output = await sharp(input).median(5).toBuffer();
|
|||||||
|
|
||||||
|
|
||||||
## blur
|
## blur
|
||||||
> blur([sigma]) ⇒ <code>Sharp</code>
|
> blur([options]) ⇒ <code>Sharp</code>
|
||||||
|
|
||||||
Blur the image.
|
Blur the image.
|
||||||
|
|
||||||
@@ -245,9 +245,12 @@ When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
|
|||||||
- <code>Error</code> Invalid parameters
|
- <code>Error</code> Invalid parameters
|
||||||
|
|
||||||
|
|
||||||
| Param | Type | Description |
|
| Param | Type | Default | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| [sigma] | <code>number</code> | a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`. |
|
| [options] | <code>Object</code> \| <code>number</code> \| <code>Boolean</code> | | |
|
||||||
|
| [options.sigma] | <code>number</code> | | a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`. |
|
||||||
|
| [options.precision] | <code>string</code> | <code>"'integer'"</code> | How accurate the operation should be, one of: integer, float, approximate. |
|
||||||
|
| [options.minAmplitude] | <code>number</code> | <code>0.2</code> | A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. |
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
@@ -580,7 +583,7 @@ Recombine the image with the specified matrix.
|
|||||||
|
|
||||||
| Param | Type | Description |
|
| Param | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| inputMatrix | <code>Array.<Array.<number>></code> | 3x3 Recombination matrix |
|
| inputMatrix | <code>Array.<Array.<number>></code> | 3x3 or 4x4 Recombination matrix |
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ A `Promise` is returned when `callback` is not provided.
|
|||||||
| Param | Type | Description |
|
| Param | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| fileOut | <code>string</code> | the path to write the image data to. |
|
| fileOut | <code>string</code> | the path to write the image data to. |
|
||||||
| [callback] | <code>function</code> | called on completion with two arguments `(err, info)`. `info` contains the output image `format`, `size` (bytes), `width`, `height`, `channels` and `premultiplied` (indicating if premultiplication was used). When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`. When using the attention crop strategy also contains `attentionX` and `attentionY`, the focal point of the cropped region. May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text. |
|
| [callback] | <code>function</code> | called on completion with two arguments `(err, info)`. `info` contains the output image `format`, `size` (bytes), `width`, `height`, `channels` and `premultiplied` (indicating if premultiplication was used). When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`. When using the attention crop strategy also contains `attentionX` and `attentionY`, the focal point of the cropped region. Animated output will also contain `pageHeight` and `pages`. May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text. |
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
```js
|
```js
|
||||||
@@ -59,6 +59,7 @@ See [withMetadata](#withmetadata) for control over this.
|
|||||||
- `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
- `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
||||||
`channels` and `premultiplied` (indicating if premultiplication was used).
|
`channels` and `premultiplied` (indicating if premultiplication was used).
|
||||||
When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
||||||
|
Animated output will also contain `pageHeight` and `pages`.
|
||||||
May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
||||||
|
|
||||||
A `Promise` is returned when `callback` is not provided.
|
A `Promise` is returned when `callback` is not provided.
|
||||||
@@ -438,6 +439,7 @@ Use these WebP options for output image.
|
|||||||
| [options.lossless] | <code>boolean</code> | <code>false</code> | use lossless compression mode |
|
| [options.lossless] | <code>boolean</code> | <code>false</code> | use lossless compression mode |
|
||||||
| [options.nearLossless] | <code>boolean</code> | <code>false</code> | use near_lossless compression mode |
|
| [options.nearLossless] | <code>boolean</code> | <code>false</code> | use near_lossless compression mode |
|
||||||
| [options.smartSubsample] | <code>boolean</code> | <code>false</code> | use high quality chroma subsampling |
|
| [options.smartSubsample] | <code>boolean</code> | <code>false</code> | use high quality chroma subsampling |
|
||||||
|
| [options.smartDeblock] | <code>boolean</code> | <code>false</code> | auto-adjust the deblocking filter, can improve low contrast edges (slow) |
|
||||||
| [options.preset] | <code>string</code> | <code>"'default'"</code> | named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text |
|
| [options.preset] | <code>string</code> | <code>"'default'"</code> | named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text |
|
||||||
| [options.effort] | <code>number</code> | <code>4</code> | CPU effort, between 0 (fastest) and 6 (slowest) |
|
| [options.effort] | <code>number</code> | <code>4</code> | CPU effort, between 0 (fastest) and 6 (slowest) |
|
||||||
| [options.loop] | <code>number</code> | <code>0</code> | number of animation iterations, use 0 for infinite animation |
|
| [options.loop] | <code>number</code> | <code>0</code> | number of animation iterations, use 0 for infinite animation |
|
||||||
@@ -693,8 +695,6 @@ Requires libvips compiled with support for libjxl.
|
|||||||
The prebuilt binaries do not include this - see
|
The prebuilt binaries do not include this - see
|
||||||
[installing a custom libvips](https://sharp.pixelplumbing.com/install#custom-libvips).
|
[installing a custom libvips](https://sharp.pixelplumbing.com/install#custom-libvips).
|
||||||
|
|
||||||
Image metadata (EXIF, XMP) is unsupported.
|
|
||||||
|
|
||||||
|
|
||||||
**Throws**:
|
**Throws**:
|
||||||
|
|
||||||
@@ -709,7 +709,9 @@ Image metadata (EXIF, XMP) is unsupported.
|
|||||||
| [options.quality] | <code>number</code> | | calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified |
|
| [options.quality] | <code>number</code> | | calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified |
|
||||||
| [options.decodingTier] | <code>number</code> | <code>0</code> | target decode speed tier, between 0 (highest quality) and 4 (lowest quality) |
|
| [options.decodingTier] | <code>number</code> | <code>0</code> | target decode speed tier, between 0 (highest quality) and 4 (lowest quality) |
|
||||||
| [options.lossless] | <code>boolean</code> | <code>false</code> | use lossless compression |
|
| [options.lossless] | <code>boolean</code> | <code>false</code> | use lossless compression |
|
||||||
| [options.effort] | <code>number</code> | <code>7</code> | CPU effort, between 3 (fastest) and 9 (slowest) |
|
| [options.effort] | <code>number</code> | <code>7</code> | CPU effort, between 1 (fastest) and 9 (slowest) |
|
||||||
|
| [options.loop] | <code>number</code> | <code>0</code> | number of animation iterations, use 0 for infinite animation |
|
||||||
|
| [options.delay] | <code>number</code> \| <code>Array.<number></code> | | delay(s) between animation frames (in milliseconds) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -760,10 +762,6 @@ Use a `.zip` or `.szi` file extension with `toFile` to write to a compressed arc
|
|||||||
|
|
||||||
The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
||||||
|
|
||||||
Requires libvips compiled with support for libgsf.
|
|
||||||
The prebuilt binaries do not include this - see
|
|
||||||
[installing a custom libvips](https://sharp.pixelplumbing.com/install#custom-libvips).
|
|
||||||
|
|
||||||
|
|
||||||
**Throws**:
|
**Throws**:
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,73 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v0.34 - *hat*
|
||||||
|
|
||||||
|
Requires libvips v8.16.0
|
||||||
|
|
||||||
|
### v0.34.0 - TBD
|
||||||
|
|
||||||
|
* Breaking: Support `info.size` on wide-character systems via upgrade to C++17.
|
||||||
|
[#3943](https://github.com/lovell/sharp/issues/3943)
|
||||||
|
|
||||||
|
* Breaking: Ensure `background` metadata can be parsed by `color` package.
|
||||||
|
[#4090](https://github.com/lovell/sharp/issues/4090)
|
||||||
|
|
||||||
|
* Add `isPalette` and `bitsPerSample` to metadata, deprecate `paletteBitDepth`.
|
||||||
|
|
||||||
|
* Expose WebP `smartDeblock` output option.
|
||||||
|
|
||||||
|
* TypeScript: Ensure channel counts use the correct range.
|
||||||
|
[#4197](https://github.com/lovell/sharp/pull/4197)
|
||||||
|
[@DavidVaness](https://github.com/DavidVaness)
|
||||||
|
|
||||||
|
* Improve support for ppc64le architecture.
|
||||||
|
[#4203](https://github.com/lovell/sharp/pull/4203)
|
||||||
|
[@sumitd2](https://github.com/sumitd2)
|
||||||
|
|
||||||
|
* Add `pdfBackground` constructor property.
|
||||||
|
[#4207](https://github.com/lovell/sharp/pull/4207)
|
||||||
|
[@calebmer](https://github.com/calebmer)
|
||||||
|
|
||||||
## v0.33 - *gauge*
|
## v0.33 - *gauge*
|
||||||
|
|
||||||
Requires libvips v8.15.2
|
Requires libvips v8.15.3
|
||||||
|
|
||||||
|
### v0.33.5 - 16th August 2024
|
||||||
|
|
||||||
|
* Upgrade to libvips v8.15.3 for upstream bug fixes.
|
||||||
|
|
||||||
|
* Add `pageHeight` and `pages` to response of multi-page output.
|
||||||
|
[#3411](https://github.com/lovell/sharp/issues/3411)
|
||||||
|
|
||||||
|
* Ensure option to force use of a globally-installed libvips works correctly.
|
||||||
|
[#4111](https://github.com/lovell/sharp/pull/4111)
|
||||||
|
[@project0](https://github.com/project0)
|
||||||
|
|
||||||
|
* Minimise use of `engines` property to improve yarn v1 support.
|
||||||
|
[#4130](https://github.com/lovell/sharp/issues/4130)
|
||||||
|
|
||||||
|
* Ensure `sharp.format.heif` includes only AVIF when using prebuilt binaries.
|
||||||
|
[#4132](https://github.com/lovell/sharp/issues/4132)
|
||||||
|
|
||||||
|
* Add support to recomb operation for 4x4 matrices.
|
||||||
|
[#4147](https://github.com/lovell/sharp/pull/4147)
|
||||||
|
[@ton11797](https://github.com/ton11797)
|
||||||
|
|
||||||
|
* Expose PNG text chunks as `comments` metadata.
|
||||||
|
[#4157](https://github.com/lovell/sharp/pull/4157)
|
||||||
|
[@nkeynes](https://github.com/nkeynes)
|
||||||
|
|
||||||
|
* Expose optional `precision` and `minAmplitude` parameters of `blur` operation.
|
||||||
|
[#4168](https://github.com/lovell/sharp/pull/4168)
|
||||||
|
[#4172](https://github.com/lovell/sharp/pull/4172)
|
||||||
|
[@marcosc90](https://github.com/marcosc90)
|
||||||
|
|
||||||
|
* Ensure `keepIccProfile` avoids colour transformation where possible.
|
||||||
|
[#4186](https://github.com/lovell/sharp/issues/4186)
|
||||||
|
|
||||||
|
* TypeScript: `chromaSubsampling` metadata is optional.
|
||||||
|
[#4191](https://github.com/lovell/sharp/pull/4191)
|
||||||
|
[@DavidVaness](https://github.com/DavidVaness)
|
||||||
|
|
||||||
### v0.33.4 - 16th May 2024
|
### v0.33.4 - 16th May 2024
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Name: Brandon Aaron
|
|||||||
GitHub: https://github.com/brandonaaron
|
GitHub: https://github.com/brandonaaron
|
||||||
|
|
||||||
Name: Andreas Lind
|
Name: Andreas Lind
|
||||||
GitHub: https://github.com/papandreouGitHub:
|
GitHub: https://github.com/papandreou
|
||||||
|
|
||||||
Name: Maurus Cuelenaere
|
Name: Maurus Cuelenaere
|
||||||
GitHub: https://github.com/mcuelenaere
|
GitHub: https://github.com/mcuelenaere
|
||||||
@@ -261,7 +261,7 @@ GitHub: https://github.com/brahima
|
|||||||
Name: Anton Marsden
|
Name: Anton Marsden
|
||||||
GitHub: https://github.com/antonmarsden
|
GitHub: https://github.com/antonmarsden
|
||||||
|
|
||||||
Name: Marcos Casagrande
|
Name: Marcos Casagrande
|
||||||
GitHub: https://github.com/marcosc90
|
GitHub: https://github.com/marcosc90
|
||||||
|
|
||||||
Name: Emanuel Jöbstl
|
Name: Emanuel Jöbstl
|
||||||
@@ -293,3 +293,18 @@ GitHub: https://github.com/mertalev
|
|||||||
|
|
||||||
Name: Adriaan Meuris
|
Name: Adriaan Meuris
|
||||||
GitHub: https://github.com/adriaanmeuris
|
GitHub: https://github.com/adriaanmeuris
|
||||||
|
|
||||||
|
Name: Richard Hillmann
|
||||||
|
GitHub: https://github.com/project0
|
||||||
|
|
||||||
|
Name: Pongsatorn Manusopit
|
||||||
|
GitHub: https://github.com/ton11797
|
||||||
|
|
||||||
|
Name: Nathan Keynes
|
||||||
|
GitHub: https://github.com/nkeynes
|
||||||
|
|
||||||
|
Name: Sumit D
|
||||||
|
GitHub: https://github.com/sumitd2
|
||||||
|
|
||||||
|
Name: Caleb Meredith
|
||||||
|
GitHub: https://github.com/calebmer
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src 'self'; object-src 'none';
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src 'self'; object-src 'none';
|
||||||
style-src 'unsafe-inline';
|
style-src 'unsafe-inline';
|
||||||
img-src 'unsafe-inline' data: https://cdn.jsdelivr.net/gh/lovell/;
|
img-src 'unsafe-inline' data: https://cdn.jsdelivr.net/gh/lovell/;
|
||||||
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://static.cloudflareinsights.com/beacon.min.js;">
|
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://static.cloudflareinsights.com/beacon.min.js/;">
|
||||||
<link rel="icon" type="image/svg+xml" href="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg">
|
<link rel="icon" type="image/svg+xml" href="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo-32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo-32.png">
|
||||||
<link rel="author" href="/humans.txt" type="text/plain">
|
<link rel="author" href="/humans.txt" type="text/plain">
|
||||||
|
|||||||
@@ -20,11 +20,6 @@ pnpm add sharp
|
|||||||
yarn add sharp
|
yarn add sharp
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh
|
|
||||||
# yarn v1 (maintenance mode)
|
|
||||||
yarn add sharp --ignore-engines
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
bun add sharp
|
bun add sharp
|
||||||
```
|
```
|
||||||
@@ -41,10 +36,11 @@ deno run --allow-ffi ...
|
|||||||
|
|
||||||
Ready-compiled sharp and libvips binaries are provided for use on the most common platforms:
|
Ready-compiled sharp and libvips binaries are provided for use on the most common platforms:
|
||||||
|
|
||||||
* macOS x64 (>= 10.13)
|
* macOS x64 (>= 10.15)
|
||||||
* macOS ARM64
|
* macOS ARM64
|
||||||
* Linux ARM (glibc >= 2.28)
|
* Linux ARM (glibc >= 2.31)
|
||||||
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
||||||
|
* Linux ppc64 (glibc >= 2.31)
|
||||||
* Linux s390x (glibc >= 2.31)
|
* Linux s390x (glibc >= 2.31)
|
||||||
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
||||||
* Windows x64
|
* Windows x64
|
||||||
@@ -92,7 +88,7 @@ Use the [supportedArchitectures](https://pnpm.io/package_json#pnpmsupportedarchi
|
|||||||
## Custom libvips
|
## Custom libvips
|
||||||
|
|
||||||
To use a custom, globally-installed version of libvips instead of the provided binaries,
|
To use a custom, globally-installed version of libvips instead of the provided binaries,
|
||||||
make sure it is at least the version listed under `engines.libvips` in the `package.json` file
|
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
||||||
and that it can be located using `pkg-config --modversion vips-cpp`.
|
and that it can be located using `pkg-config --modversion vips-cpp`.
|
||||||
|
|
||||||
For help compiling libvips and its dependencies, please see
|
For help compiling libvips and its dependencies, please see
|
||||||
@@ -115,7 +111,7 @@ environment variables.
|
|||||||
|
|
||||||
Building from source requires:
|
Building from source requires:
|
||||||
|
|
||||||
* C++11 compiler
|
* C++17 compiler
|
||||||
* [node-addon-api](https://www.npmjs.com/package/node-addon-api) version 7+
|
* [node-addon-api](https://www.npmjs.com/package/node-addon-api) version 7+
|
||||||
* [node-gyp](https://github.com/nodejs/node-gyp#installation) version 9+ and its dependencies
|
* [node-gyp](https://github.com/nodejs/node-gyp#installation) version 9+ and its dependencies
|
||||||
|
|
||||||
@@ -139,6 +135,8 @@ Use in web browsers is unsupported.
|
|||||||
|
|
||||||
Native text rendering is unsupported.
|
Native text rendering is unsupported.
|
||||||
|
|
||||||
|
[Tile-based output](/api-output#tile) is unsupported.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install --cpu=wasm32 sharp
|
npm install --cpu=wasm32 sharp
|
||||||
```
|
```
|
||||||
@@ -240,8 +238,10 @@ custom:
|
|||||||
|
|
||||||
### electron
|
### electron
|
||||||
|
|
||||||
|
#### electron-builder
|
||||||
|
|
||||||
Ensure `sharp` is unpacked from the ASAR archive file using the
|
Ensure `sharp` is unpacked from the ASAR archive file using the
|
||||||
[asarUnpack](https://www.electron.build/configuration/configuration.html)
|
[asarUnpack](https://www.electron.build/app-builder-lib.interface.platformspecificbuildoptions#asarunpack)
|
||||||
option.
|
option.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -256,6 +256,22 @@ option.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### electron-forge
|
||||||
|
|
||||||
|
Ensure `sharp` is unpacked from the ASAR archive file using the
|
||||||
|
[unpack](https://js.electronforge.io/interfaces/_electron_forge_maker_squirrel.InternalOptions.Options.html#asar)
|
||||||
|
option.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"packagerConfig": {
|
||||||
|
"asar": {
|
||||||
|
"unpack": "**/node_modules/{sharp,@img}/**/*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### vite
|
### vite
|
||||||
|
|
||||||
Ensure `sharp` is excluded from bundling via the
|
Ensure `sharp` is excluded from bundling via the
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ try {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const gyp = require('node-gyp');
|
const gyp = require('node-gyp');
|
||||||
log(`Found node-gyp version ${gyp().version}`);
|
log(`Found node-gyp ${gyp().version}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log('Please add node-gyp to your dependencies');
|
log('Please add node-gyp to your dependencies');
|
||||||
return;
|
return;
|
||||||
@@ -30,7 +30,7 @@ try {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (useGlobalLibvips()) {
|
if (useGlobalLibvips(log)) {
|
||||||
buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
|
buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
|
||||||
} else if (process.env.npm_config_build_from_source) {
|
} else if (process.env.npm_config_build_from_source) {
|
||||||
buildFromSource('Detected --build-from-source flag');
|
buildFromSource('Detected --build-from-source flag');
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ function bandbool (boolOp) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with channel-related functions.
|
* Decorate the Sharp prototype with channel-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ function tint (tint) {
|
|||||||
/**
|
/**
|
||||||
* Convert to 8-bit greyscale; 256 shades of grey.
|
* Convert to 8-bit greyscale; 256 shades of grey.
|
||||||
* This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
|
* This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
|
||||||
* By default the output image will be web-friendly sRGB and contain three (identical) color channels.
|
* By default the output image will be web-friendly sRGB and contain three (identical) colour channels.
|
||||||
* This may be overridden by other sharp operations such as `toColourspace('b-w')`,
|
* This may be overridden by other sharp operations such as `toColourspace('b-w')`,
|
||||||
* which will produce an output image containing one color channel.
|
* which will produce an output image containing one colour channel.
|
||||||
* An alpha channel may be present, and will be unchanged by the operation.
|
* An alpha channel may be present, and will be unchanged by the operation.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
@@ -159,6 +159,7 @@ function _setBackgroundColourOption (key, value) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with colour-related functions.
|
* Decorate the Sharp prototype with colour-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ const blend = {
|
|||||||
* The images to composite must be the same size or smaller than the processed image.
|
* The images to composite must be the same size or smaller than the processed image.
|
||||||
* If both `top` and `left` options are provided, they take precedence over `gravity`.
|
* If both `top` and `left` options are provided, they take precedence over `gravity`.
|
||||||
*
|
*
|
||||||
* Any resize, rotate or extract operations in the same processing pipeline
|
* Other operations in the same processing pipeline (e.g. resize, rotate, flip,
|
||||||
* will always be applied to the input image before composition.
|
* flop, extract) will always be applied to the input image before composition.
|
||||||
*
|
*
|
||||||
* The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
|
* The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
|
||||||
* `dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
|
* `dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
|
||||||
@@ -202,6 +202,7 @@ function composite (images) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with composite-related functions.
|
* Decorate the Sharp prototype with composite-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ const debuglog = util.debuglog('sharp');
|
|||||||
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
|
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
|
||||||
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
|
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
|
||||||
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
|
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
|
||||||
|
* @param {string|Object} [options.pdfBackground] - Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick.
|
||||||
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
|
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
|
||||||
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
|
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||||
* @param {number} [options.raw.width] - integral number of pixels wide.
|
* @param {number} [options.raw.width] - integral number of pixels wide.
|
||||||
@@ -226,6 +227,8 @@ const Sharp = function (input, options) {
|
|||||||
negateAlpha: true,
|
negateAlpha: true,
|
||||||
medianSize: 0,
|
medianSize: 0,
|
||||||
blurSigma: 0,
|
blurSigma: 0,
|
||||||
|
precision: 'integer',
|
||||||
|
minAmpl: 0.2,
|
||||||
sharpenSigma: 0,
|
sharpenSigma: 0,
|
||||||
sharpenM1: 1,
|
sharpenM1: 1,
|
||||||
sharpenM2: 2,
|
sharpenM2: 2,
|
||||||
@@ -297,6 +300,7 @@ const Sharp = function (input, options) {
|
|||||||
webpLossless: false,
|
webpLossless: false,
|
||||||
webpNearLossless: false,
|
webpNearLossless: false,
|
||||||
webpSmartSubsample: false,
|
webpSmartSubsample: false,
|
||||||
|
webpSmartDeblock: false,
|
||||||
webpPreset: 'default',
|
webpPreset: 'default',
|
||||||
webpEffort: 4,
|
webpEffort: 4,
|
||||||
webpMinSize: false,
|
webpMinSize: false,
|
||||||
@@ -346,6 +350,7 @@ const Sharp = function (input, options) {
|
|||||||
timeoutSeconds: 0,
|
timeoutSeconds: 0,
|
||||||
linearA: [],
|
linearA: [],
|
||||||
linearB: [],
|
linearB: [],
|
||||||
|
pdfBackground: [255, 255, 255, 255],
|
||||||
// Function to notify of libvips warnings
|
// Function to notify of libvips warnings
|
||||||
debuglog: warning => {
|
debuglog: warning => {
|
||||||
this.emit('warning', warning);
|
this.emit('warning', warning);
|
||||||
@@ -445,6 +450,7 @@ Object.assign(Sharp.prototype, { clone });
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Export constructor.
|
* Export constructor.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = Sharp;
|
module.exports = Sharp;
|
||||||
|
|||||||
76
lib/index.d.ts
vendored
@@ -244,14 +244,14 @@ declare namespace sharp {
|
|||||||
* @param tint Parsed by the color module.
|
* @param tint Parsed by the color module.
|
||||||
* @returns A sharp instance that can be used to chain operations
|
* @returns A sharp instance that can be used to chain operations
|
||||||
*/
|
*/
|
||||||
tint(tint: Color): Sharp;
|
tint(tint: Colour | Color): Sharp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert to 8-bit greyscale; 256 shades of grey.
|
* Convert to 8-bit greyscale; 256 shades of grey.
|
||||||
* This is a linear operation.
|
* This is a linear operation.
|
||||||
* If the input image is in a non-linear colour space such as sRGB, use gamma() with greyscale() for the best results.
|
* If the input image is in a non-linear colour space such as sRGB, use gamma() with greyscale() for the best results.
|
||||||
* By default the output image will be web-friendly sRGB and contain three (identical) color channels.
|
* By default the output image will be web-friendly sRGB and contain three (identical) colour channels.
|
||||||
* This may be overridden by other sharp operations such as toColourspace('b-w'), which will produce an output image containing one color channel.
|
* This may be overridden by other sharp operations such as toColourspace('b-w'), which will produce an output image containing one colour channel.
|
||||||
* An alpha channel may be present, and will be unchanged by the operation.
|
* An alpha channel may be present, and will be unchanged by the operation.
|
||||||
* @param greyscale true to enable and false to disable (defaults to true)
|
* @param greyscale true to enable and false to disable (defaults to true)
|
||||||
* @returns A sharp instance that can be used to chain operations
|
* @returns A sharp instance that can be used to chain operations
|
||||||
@@ -401,7 +401,7 @@ declare namespace sharp {
|
|||||||
/**
|
/**
|
||||||
* Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
* Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
||||||
* You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
* You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
||||||
* By default, new pixels are filled with a black background. You can provide a background color with the `background` option.
|
* By default, new pixels are filled with a black background. You can provide a background colour with the `background` option.
|
||||||
* A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
* A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
||||||
*
|
*
|
||||||
* In the case of a 2x2 matrix, the transform is:
|
* In the case of a 2x2 matrix, the transform is:
|
||||||
@@ -464,7 +464,7 @@ declare namespace sharp {
|
|||||||
* @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
|
||||||
*/
|
*/
|
||||||
blur(sigma?: number | boolean): Sharp;
|
blur(sigma?: number | boolean | BlurOptions): Sharp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge alpha transparency channel, if any, with background.
|
* Merge alpha transparency channel, if any, with background.
|
||||||
@@ -571,11 +571,11 @@ declare namespace sharp {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recomb the image with the specified matrix.
|
* Recomb the image with the specified matrix.
|
||||||
* @param inputMatrix 3x3 Recombination matrix
|
* @param inputMatrix 3x3 Recombination matrix or 4x4 Recombination matrix
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
recomb(inputMatrix: Matrix3x3): Sharp;
|
recomb(inputMatrix: Matrix3x3 | Matrix4x4): Sharp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the image using brightness, saturation, hue rotation and lightness.
|
* Transforms the image using brightness, saturation, hue rotation and lightness.
|
||||||
@@ -799,8 +799,6 @@ declare namespace sharp {
|
|||||||
* Use tile-based deep zoom (image pyramid) output.
|
* Use tile-based deep zoom (image pyramid) output.
|
||||||
* Set the format and options for tile images via the toFormat, jpeg, png or webp functions.
|
* Set the format and options for tile images via the toFormat, jpeg, png or webp functions.
|
||||||
* Use a .zip or .szi file extension with toFile to write to a compressed archive file format.
|
* Use a .zip or .szi file extension with toFile to write to a compressed archive file format.
|
||||||
*
|
|
||||||
* Warning: multiple sharp instances concurrently producing tile output can expose a possible race condition in some versions of libgsf.
|
|
||||||
* @param tile tile options
|
* @param tile tile options
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
* @returns A sharp instance that can be used to chain operations
|
* @returns A sharp instance that can be used to chain operations
|
||||||
@@ -935,6 +933,8 @@ declare namespace sharp {
|
|||||||
subifd?: number | undefined;
|
subifd?: number | undefined;
|
||||||
/** Level to extract from a multi-level input (OpenSlide), zero based. (optional, default 0) */
|
/** Level to extract from a multi-level input (OpenSlide), zero based. (optional, default 0) */
|
||||||
level?: number | undefined;
|
level?: number | undefined;
|
||||||
|
/** Background colour to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. */
|
||||||
|
pdfBackground?: Colour | Color | undefined;
|
||||||
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
|
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
|
||||||
animated?: boolean | undefined;
|
animated?: boolean | undefined;
|
||||||
/** Describes raw pixel input image data. See raw() for pixel ordering. */
|
/** Describes raw pixel input image data. See raw() for pixel ordering. */
|
||||||
@@ -969,7 +969,7 @@ declare namespace sharp {
|
|||||||
interface Raw {
|
interface Raw {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
channels: 1 | 2 | 3 | 4;
|
channels: Channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateRaw extends Raw {
|
interface CreateRaw extends Raw {
|
||||||
@@ -977,15 +977,17 @@ declare namespace sharp {
|
|||||||
premultiplied?: boolean | undefined;
|
premultiplied?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateChannels = 3 | 4;
|
||||||
|
|
||||||
interface Create {
|
interface Create {
|
||||||
/** Number of pixels wide. */
|
/** Number of pixels wide. */
|
||||||
width: number;
|
width: number;
|
||||||
/** Number of pixels high. */
|
/** Number of pixels high. */
|
||||||
height: number;
|
height: number;
|
||||||
/** Number of bands e.g. 3 for RGB, 4 for RGBA */
|
/** Number of bands, 3 for RGB, 4 for RGBA */
|
||||||
channels: Channels;
|
channels: CreateChannels;
|
||||||
/** Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. */
|
/** Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. */
|
||||||
background: Color;
|
background: Colour | Color;
|
||||||
/** Describes a noise to be created. */
|
/** Describes a noise to be created. */
|
||||||
noise?: Noise | undefined;
|
noise?: Noise | undefined;
|
||||||
}
|
}
|
||||||
@@ -1069,9 +1071,13 @@ declare namespace sharp {
|
|||||||
/** Number of pixels per inch (DPI), if present */
|
/** Number of pixels per inch (DPI), if present */
|
||||||
density?: number | undefined;
|
density?: number | undefined;
|
||||||
/** String containing JPEG chroma subsampling, 4:2:0 or 4:4:4 for RGB, 4:2:0:4 or 4:4:4:4 for CMYK */
|
/** String containing JPEG chroma subsampling, 4:2:0 or 4:4:4 for RGB, 4:2:0:4 or 4:4:4:4 for CMYK */
|
||||||
chromaSubsampling: string;
|
chromaSubsampling?: string | undefined;
|
||||||
/** Boolean indicating whether the image is interlaced using a progressive scan */
|
/** Boolean indicating whether the image is interlaced using a progressive scan */
|
||||||
isProgressive?: boolean | undefined;
|
isProgressive?: boolean | undefined;
|
||||||
|
/** Boolean indicating whether the image is palette-based (GIF, PNG). */
|
||||||
|
isPalette?: boolean | undefined;
|
||||||
|
/** Number of bits per sample for each channel (GIF, PNG). */
|
||||||
|
bitsPerSample?: number | undefined;
|
||||||
/** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */
|
/** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */
|
||||||
pages?: number | undefined;
|
pages?: number | undefined;
|
||||||
/** Number of pixels high each page in a multi-page image will be. */
|
/** Number of pixels high each page in a multi-page image will be. */
|
||||||
@@ -1098,8 +1104,8 @@ declare namespace sharp {
|
|||||||
tifftagPhotoshop?: Buffer | undefined;
|
tifftagPhotoshop?: Buffer | undefined;
|
||||||
/** The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) */
|
/** The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) */
|
||||||
compression?: 'av1' | 'hevc';
|
compression?: 'av1' | 'hevc';
|
||||||
/** Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value */
|
/** Default background colour, if present, for PNG (bKGD) and GIF images */
|
||||||
background?: { r: number; g: number; b: number } | number;
|
background?: { r: number; g: number; b: number } | { gray: number };
|
||||||
/** Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide */
|
/** Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide */
|
||||||
levels?: LevelMetadata[] | undefined;
|
levels?: LevelMetadata[] | undefined;
|
||||||
/** Number of Sub Image File Directories in an OME-TIFF image */
|
/** Number of Sub Image File Directories in an OME-TIFF image */
|
||||||
@@ -1108,6 +1114,8 @@ declare namespace sharp {
|
|||||||
resolutionUnit?: 'inch' | 'cm' | undefined;
|
resolutionUnit?: 'inch' | 'cm' | undefined;
|
||||||
/** String containing format for images loaded via *magick */
|
/** String containing format for images loaded via *magick */
|
||||||
formatMagick?: string | undefined;
|
formatMagick?: string | undefined;
|
||||||
|
/** Array of keyword/text pairs representing PNG text blocks, if present. */
|
||||||
|
comments?: CommentsMetadata[] | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LevelMetadata {
|
interface LevelMetadata {
|
||||||
@@ -1115,6 +1123,11 @@ declare namespace sharp {
|
|||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CommentsMetadata {
|
||||||
|
keyword: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface Stats {
|
interface Stats {
|
||||||
/** Array of channel statistics for each channel in the image. */
|
/** Array of channel statistics for each channel in the image. */
|
||||||
channels: ChannelStats[];
|
channels: ChannelStats[];
|
||||||
@@ -1332,12 +1345,23 @@ declare namespace sharp {
|
|||||||
|
|
||||||
interface RotateOptions {
|
interface RotateOptions {
|
||||||
/** parsed by the color module to extract values for red, green, blue and alpha. (optional, default "#000000") */
|
/** parsed by the color module to extract values for red, green, blue and alpha. (optional, default "#000000") */
|
||||||
background?: Color | undefined;
|
background?: Colour | Color | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Precision = 'integer' | 'float' | 'approximate';
|
||||||
|
|
||||||
|
interface BlurOptions {
|
||||||
|
/** A value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2` */
|
||||||
|
sigma: number;
|
||||||
|
/** A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. */
|
||||||
|
minAmplitude?: number;
|
||||||
|
/** How accurate the operation should be, one of: integer, float, approximate. (optional, default "integer") */
|
||||||
|
precision?: Precision | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FlattenOptions {
|
interface FlattenOptions {
|
||||||
/** background colour, parsed by the color module, defaults to black. (optional, default {r:0,g:0,b:0}) */
|
/** background colour, parsed by the color module, defaults to black. (optional, default {r:0,g:0,b:0}) */
|
||||||
background?: Color | undefined;
|
background?: Colour | Color | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NegateOptions {
|
interface NegateOptions {
|
||||||
@@ -1362,7 +1386,7 @@ declare namespace sharp {
|
|||||||
/** Position, gravity or strategy to use when fit is cover or contain. (optional, default 'centre') */
|
/** Position, gravity or strategy to use when fit is cover or contain. (optional, default 'centre') */
|
||||||
position?: number | string | undefined;
|
position?: number | string | undefined;
|
||||||
/** Background colour when using a fit of contain, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
/** Background colour when using a fit of contain, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
||||||
background?: Color | undefined;
|
background?: Colour | Color | undefined;
|
||||||
/** The kernel to use for image reduction. (optional, default 'lanczos3') */
|
/** The kernel to use for image reduction. (optional, default 'lanczos3') */
|
||||||
kernel?: keyof KernelEnum | undefined;
|
kernel?: keyof KernelEnum | undefined;
|
||||||
/** Do not enlarge if the width or height are already less than the specified dimensions, equivalent to GraphicsMagick's > geometry option. (optional, default false) */
|
/** Do not enlarge if the width or height are already less than the specified dimensions, equivalent to GraphicsMagick's > geometry option. (optional, default false) */
|
||||||
@@ -1405,14 +1429,14 @@ declare namespace sharp {
|
|||||||
/** single pixel count to right edge (optional, default 0) */
|
/** single pixel count to right edge (optional, default 0) */
|
||||||
right?: number | undefined;
|
right?: number | undefined;
|
||||||
/** background colour, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
/** background colour, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
||||||
background?: Color | undefined;
|
background?: Colour | Color | undefined;
|
||||||
/** how the extension is done, one of: "background", "copy", "repeat", "mirror" (optional, default `'background'`) */
|
/** how the extension is done, one of: "background", "copy", "repeat", "mirror" (optional, default `'background'`) */
|
||||||
extendWith?: ExtendWith | undefined;
|
extendWith?: ExtendWith | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
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?: Colour | Color | undefined;
|
||||||
/** 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) */
|
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
||||||
@@ -1423,8 +1447,8 @@ declare namespace sharp {
|
|||||||
depth?: 'char' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'float' | 'complex' | 'double' | 'dpcomplex';
|
depth?: 'char' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'float' | 'complex' | 'double' | 'dpcomplex';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 3 for sRGB, 4 for CMYK */
|
/** 1 for grayscale, 2 for grayscale + alpha, 3 for sRGB, 4 for CMYK or RGBA */
|
||||||
type Channels = 3 | 4;
|
type Channels = 1 | 2 | 3 | 4;
|
||||||
|
|
||||||
interface RGBA {
|
interface RGBA {
|
||||||
r?: number | undefined;
|
r?: number | undefined;
|
||||||
@@ -1433,7 +1457,8 @@ declare namespace sharp {
|
|||||||
alpha?: number | undefined;
|
alpha?: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Color = string | RGBA;
|
type Colour = string | RGBA;
|
||||||
|
type Color = Colour;
|
||||||
|
|
||||||
interface Kernel {
|
interface Kernel {
|
||||||
/** width of the kernel in pixels. */
|
/** width of the kernel in pixels. */
|
||||||
@@ -1558,7 +1583,7 @@ declare namespace sharp {
|
|||||||
size: number;
|
size: number;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
channels: 1 | 2 | 3 | 4;
|
channels: Channels;
|
||||||
/** indicating if premultiplication was used */
|
/** indicating if premultiplication was used */
|
||||||
premultiplied: boolean;
|
premultiplied: boolean;
|
||||||
/** Only defined when using a crop strategy */
|
/** Only defined when using a crop strategy */
|
||||||
@@ -1730,6 +1755,7 @@ declare namespace sharp {
|
|||||||
|
|
||||||
type Matrix2x2 = [[number, number], [number, number]];
|
type Matrix2x2 = [[number, number], [number, number]];
|
||||||
type Matrix3x3 = [[number, number, number], [number, number, number], [number, number, number]];
|
type Matrix3x3 = [[number, number, number], [number, number, number], [number, number, number]];
|
||||||
|
type Matrix4x4 = [[number, number, number, number], [number, number, number, number], [number, number, number, number], [number, number, number, number]];
|
||||||
}
|
}
|
||||||
|
|
||||||
export = sharp;
|
export = sharp;
|
||||||
|
|||||||
19
lib/input.js
@@ -8,7 +8,7 @@ const is = require('./is');
|
|||||||
const sharp = require('./sharp');
|
const sharp = require('./sharp');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Justication alignment
|
* Justification alignment
|
||||||
* @member
|
* @member
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@@ -24,9 +24,9 @@ const align = {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _inputOptionsFromObject (obj) {
|
function _inputOptionsFromObject (obj) {
|
||||||
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd } = obj;
|
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground } = obj;
|
||||||
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd].some(is.defined)
|
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground].some(is.defined)
|
||||||
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd }
|
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground }
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +222,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|||||||
throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd);
|
throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// PDF background colour
|
||||||
|
if (is.defined(inputOptions.pdfBackground)) {
|
||||||
|
this._setBackgroundColourOption('pdfBackground', inputOptions.pdfBackground);
|
||||||
|
}
|
||||||
// Create new image
|
// Create new image
|
||||||
if (is.defined(inputOptions.create)) {
|
if (is.defined(inputOptions.create)) {
|
||||||
if (
|
if (
|
||||||
@@ -430,15 +434,16 @@ function _isStreamInput () {
|
|||||||
* - `density`: Number of pixels per inch (DPI), if present
|
* - `density`: Number of pixels per inch (DPI), if present
|
||||||
* - `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
* - `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
||||||
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||||
|
* - `isPalette`: Boolean indicating whether the image is palette-based (GIF, PNG).
|
||||||
|
* - `bitsPerSample`: Number of bits per sample for each channel (GIF, PNG, HEIF).
|
||||||
* - `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
* - `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
||||||
* - `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
* - `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
||||||
* - `paletteBitDepth`: Bit depth of palette-based image (GIF, PNG).
|
|
||||||
* - `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
* - `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
||||||
* - `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
* - `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
||||||
* - `pagePrimary`: Number of the primary page in a HEIF image
|
* - `pagePrimary`: Number of the primary page in a HEIF image
|
||||||
* - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
* - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
||||||
* - `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
* - `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
||||||
* - `background`: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value
|
* - `background`: Default background colour, if present, for PNG (bKGD) and GIF images
|
||||||
* - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
|
* - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
|
||||||
* - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
|
* - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
|
||||||
* - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
* - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
||||||
@@ -450,6 +455,7 @@ function _isStreamInput () {
|
|||||||
* - `xmp`: Buffer containing raw XMP data, if present
|
* - `xmp`: Buffer containing raw XMP data, if present
|
||||||
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
||||||
* - `formatMagick`: String containing format for images loaded via *magick
|
* - `formatMagick`: String containing format for images loaded via *magick
|
||||||
|
* - `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const metadata = await sharp(input).metadata();
|
* const metadata = await sharp(input).metadata();
|
||||||
@@ -638,6 +644,7 @@ function stats (callback) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with input-related functions.
|
* Decorate the Sharp prototype with input-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
|||||||
const semverSatisfies = require('semver/functions/satisfies');
|
const semverSatisfies = require('semver/functions/satisfies');
|
||||||
const detectLibc = require('detect-libc');
|
const detectLibc = require('detect-libc');
|
||||||
|
|
||||||
const { engines, optionalDependencies } = require('../package.json');
|
const { config, engines, optionalDependencies } = require('../package.json');
|
||||||
|
|
||||||
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
||||||
engines.libvips;
|
config.libvips;
|
||||||
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
||||||
|
|
||||||
const prebuiltPlatforms = [
|
const prebuiltPlatforms = [
|
||||||
@@ -162,21 +162,23 @@ const pkgConfigPath = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const skipSearch = (status, reason) => {
|
const skipSearch = (status, reason, logger) => {
|
||||||
log(`Detected ${reason}, skipping search for globally-installed libvips`);
|
if (logger) {
|
||||||
|
logger(`Detected ${reason}, skipping search for globally-installed libvips`);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useGlobalLibvips = () => {
|
const useGlobalLibvips = (logger) => {
|
||||||
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
||||||
return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS');
|
return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS', logger);
|
||||||
}
|
}
|
||||||
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
||||||
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS');
|
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS', logger);
|
||||||
}
|
}
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (isRosetta()) {
|
if (isRosetta()) {
|
||||||
return skipSearch(false, 'Rosetta');
|
return skipSearch(false, 'Rosetta', logger);
|
||||||
}
|
}
|
||||||
const globalVipsVersion = globalLibvipsVersion();
|
const globalVipsVersion = globalLibvipsVersion();
|
||||||
return !!globalVipsVersion && /* istanbul ignore next */
|
return !!globalVipsVersion && /* istanbul ignore next */
|
||||||
|
|||||||
@@ -6,6 +6,17 @@
|
|||||||
const color = require('color');
|
const color = require('color');
|
||||||
const is = require('./is');
|
const is = require('./is');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How accurate an operation should be.
|
||||||
|
* @member
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
const vipsPrecision = {
|
||||||
|
integer: 'integer',
|
||||||
|
float: 'float',
|
||||||
|
approximate: 'approximate'
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate the output image by either an explicit angle
|
* Rotate the output image by either an explicit angle
|
||||||
* or auto-orient based on the EXIF `Orientation` tag.
|
* or auto-orient based on the EXIF `Orientation` tag.
|
||||||
@@ -117,7 +128,7 @@ function flop (flop) {
|
|||||||
* Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
* Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
|
||||||
*
|
*
|
||||||
* You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
* You must provide an array of length 4 or a 2x2 affine transformation matrix.
|
||||||
* By default, new pixels are filled with a black background. You can provide a background color with the `background` option.
|
* By default, new pixels are filled with a black background. You can provide a background colour with the `background` option.
|
||||||
* A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
* A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
|
||||||
*
|
*
|
||||||
* In the case of a 2x2 matrix, the transform is:
|
* In the case of a 2x2 matrix, the transform is:
|
||||||
@@ -367,23 +378,51 @@ function median (size) {
|
|||||||
* .blur(5)
|
* .blur(5)
|
||||||
* .toBuffer();
|
* .toBuffer();
|
||||||
*
|
*
|
||||||
* @param {number} [sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
* @param {Object|number|Boolean} [options]
|
||||||
|
* @param {number} [options.sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
|
||||||
|
* @param {string} [options.precision='integer'] How accurate the operation should be, one of: integer, float, approximate.
|
||||||
|
* @param {number} [options.minAmplitude=0.2] A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask.
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid parameters
|
* @throws {Error} Invalid parameters
|
||||||
*/
|
*/
|
||||||
function blur (sigma) {
|
function blur (options) {
|
||||||
if (!is.defined(sigma)) {
|
let sigma;
|
||||||
|
if (is.number(options)) {
|
||||||
|
sigma = options;
|
||||||
|
} else if (is.plainObject(options)) {
|
||||||
|
if (!is.number(options.sigma)) {
|
||||||
|
throw is.invalidParameterError('options.sigma', 'number between 0.3 and 1000', sigma);
|
||||||
|
}
|
||||||
|
sigma = options.sigma;
|
||||||
|
if ('precision' in options) {
|
||||||
|
if (is.string(vipsPrecision[options.precision])) {
|
||||||
|
this.options.precision = vipsPrecision[options.precision];
|
||||||
|
} else {
|
||||||
|
throw is.invalidParameterError('precision', 'one of: integer, float, approximate', options.precision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ('minAmplitude' in options) {
|
||||||
|
if (is.number(options.minAmplitude) && is.inRange(options.minAmplitude, 0.001, 1)) {
|
||||||
|
this.options.minAmpl = options.minAmplitude;
|
||||||
|
} else {
|
||||||
|
throw is.invalidParameterError('minAmplitude', 'number between 0.001 and 1', options.minAmplitude);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.defined(options)) {
|
||||||
// No arguments: default to mild blur
|
// No arguments: default to mild blur
|
||||||
this.options.blurSigma = -1;
|
this.options.blurSigma = -1;
|
||||||
} else if (is.bool(sigma)) {
|
} else if (is.bool(options)) {
|
||||||
// Boolean argument: apply mild blur?
|
// Boolean argument: apply mild blur?
|
||||||
this.options.blurSigma = sigma ? -1 : 0;
|
this.options.blurSigma = options ? -1 : 0;
|
||||||
} else if (is.number(sigma) && is.inRange(sigma, 0.3, 1000)) {
|
} else if (is.number(sigma) && is.inRange(sigma, 0.3, 1000)) {
|
||||||
// Numeric argument: specific sigma
|
// Numeric argument: specific sigma
|
||||||
this.options.blurSigma = sigma;
|
this.options.blurSigma = sigma;
|
||||||
} else {
|
} else {
|
||||||
throw is.invalidParameterError('sigma', 'number between 0.3 and 1000', sigma);
|
throw is.invalidParameterError('sigma', 'number between 0.3 and 1000', sigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,24 +826,22 @@ function linear (a, b) {
|
|||||||
* // With this example input, a sepia filter has been applied
|
* // With this example input, a sepia filter has been applied
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* @param {Array<Array<number>>} inputMatrix - 3x3 Recombination matrix
|
* @param {Array<Array<number>>} inputMatrix - 3x3 or 4x4 Recombination matrix
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid parameters
|
* @throws {Error} Invalid parameters
|
||||||
*/
|
*/
|
||||||
function recomb (inputMatrix) {
|
function recomb (inputMatrix) {
|
||||||
if (!Array.isArray(inputMatrix) || inputMatrix.length !== 3 ||
|
if (!Array.isArray(inputMatrix)) {
|
||||||
inputMatrix[0].length !== 3 ||
|
throw is.invalidParameterError('inputMatrix', 'array', inputMatrix);
|
||||||
inputMatrix[1].length !== 3 ||
|
|
||||||
inputMatrix[2].length !== 3
|
|
||||||
) {
|
|
||||||
// must pass in a kernel
|
|
||||||
throw new Error('Invalid recombination matrix');
|
|
||||||
}
|
}
|
||||||
this.options.recombMatrix = [
|
if (inputMatrix.length !== 3 && inputMatrix.length !== 4) {
|
||||||
inputMatrix[0][0], inputMatrix[0][1], inputMatrix[0][2],
|
throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', inputMatrix.length);
|
||||||
inputMatrix[1][0], inputMatrix[1][1], inputMatrix[1][2],
|
}
|
||||||
inputMatrix[2][0], inputMatrix[2][1], inputMatrix[2][2]
|
const recombMatrix = inputMatrix.flat().map(Number);
|
||||||
].map(Number);
|
if (recombMatrix.length !== 9 && recombMatrix.length !== 16) {
|
||||||
|
throw is.invalidParameterError('inputMatrix', 'cardinality of 9 or 16', recombMatrix.length);
|
||||||
|
}
|
||||||
|
this.options.recombMatrix = recombMatrix;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,6 +930,7 @@ function modulate (options) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with operation-related functions.
|
* Decorate the Sharp prototype with operation-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ const bitdepthFromColourCount = (colours) => 1 << 31 - Math.clz32(Math.ceil(Math
|
|||||||
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
||||||
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
||||||
* When using the attention crop strategy also contains `attentionX` and `attentionY`, the focal point of the cropped region.
|
* When using the attention crop strategy also contains `attentionX` and `attentionY`, the focal point of the cropped region.
|
||||||
|
* Animated output will also contain `pageHeight` and `pages`.
|
||||||
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
||||||
* @returns {Promise<Object>} - when no callback is provided
|
* @returns {Promise<Object>} - when no callback is provided
|
||||||
* @throws {Error} Invalid parameters
|
* @throws {Error} Invalid parameters
|
||||||
@@ -109,6 +110,7 @@ function toFile (fileOut, callback) {
|
|||||||
* - `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
* - `info` contains the output image `format`, `size` (bytes), `width`, `height`,
|
||||||
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
* `channels` and `premultiplied` (indicating if premultiplication was used).
|
||||||
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
* When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.
|
||||||
|
* Animated output will also contain `pageHeight` and `pages`.
|
||||||
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
||||||
*
|
*
|
||||||
* A `Promise` is returned when `callback` is not provided.
|
* A `Promise` is returned when `callback` is not provided.
|
||||||
@@ -621,6 +623,7 @@ function png (options) {
|
|||||||
* @param {boolean} [options.lossless=false] - use lossless compression mode
|
* @param {boolean} [options.lossless=false] - use lossless compression mode
|
||||||
* @param {boolean} [options.nearLossless=false] - use near_lossless compression mode
|
* @param {boolean} [options.nearLossless=false] - use near_lossless compression mode
|
||||||
* @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling
|
* @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling
|
||||||
|
* @param {boolean} [options.smartDeblock=false] - auto-adjust the deblocking filter, can improve low contrast edges (slow)
|
||||||
* @param {string} [options.preset='default'] - named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text
|
* @param {string} [options.preset='default'] - named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text
|
||||||
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest)
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest)
|
||||||
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
||||||
@@ -656,6 +659,9 @@ function webp (options) {
|
|||||||
if (is.defined(options.smartSubsample)) {
|
if (is.defined(options.smartSubsample)) {
|
||||||
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
|
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
|
||||||
}
|
}
|
||||||
|
if (is.defined(options.smartDeblock)) {
|
||||||
|
this._setBooleanOption('webpSmartDeblock', options.smartDeblock);
|
||||||
|
}
|
||||||
if (is.defined(options.preset)) {
|
if (is.defined(options.preset)) {
|
||||||
if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) {
|
if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) {
|
||||||
this.options.webpPreset = options.preset;
|
this.options.webpPreset = options.preset;
|
||||||
@@ -1121,8 +1127,6 @@ function heif (options) {
|
|||||||
* The prebuilt binaries do not include this - see
|
* The prebuilt binaries do not include this - see
|
||||||
* {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
|
* {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
|
||||||
*
|
*
|
||||||
* Image metadata (EXIF, XMP) is unsupported.
|
|
||||||
*
|
|
||||||
* @since 0.31.3
|
* @since 0.31.3
|
||||||
*
|
*
|
||||||
* @param {Object} [options] - output options
|
* @param {Object} [options] - output options
|
||||||
@@ -1130,7 +1134,9 @@ function heif (options) {
|
|||||||
* @param {number} [options.quality] - calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified
|
* @param {number} [options.quality] - calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified
|
||||||
* @param {number} [options.decodingTier=0] - target decode speed tier, between 0 (highest quality) and 4 (lowest quality)
|
* @param {number} [options.decodingTier=0] - target decode speed tier, between 0 (highest quality) and 4 (lowest quality)
|
||||||
* @param {boolean} [options.lossless=false] - use lossless compression
|
* @param {boolean} [options.lossless=false] - use lossless compression
|
||||||
* @param {number} [options.effort=7] - CPU effort, between 3 (fastest) and 9 (slowest)
|
* @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 9 (slowest)
|
||||||
|
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
||||||
|
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
||||||
* @returns {Sharp}
|
* @returns {Sharp}
|
||||||
* @throws {Error} Invalid options
|
* @throws {Error} Invalid options
|
||||||
*/
|
*/
|
||||||
@@ -1167,13 +1173,14 @@ function jxl (options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is.defined(options.effort)) {
|
if (is.defined(options.effort)) {
|
||||||
if (is.integer(options.effort) && is.inRange(options.effort, 3, 9)) {
|
if (is.integer(options.effort) && is.inRange(options.effort, 1, 9)) {
|
||||||
this.options.jxlEffort = options.effort;
|
this.options.jxlEffort = options.effort;
|
||||||
} else {
|
} else {
|
||||||
throw is.invalidParameterError('effort', 'integer between 3 and 9', options.effort);
|
throw is.invalidParameterError('effort', 'integer between 1 and 9', options.effort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trySetAnimationOptions(options, this.options);
|
||||||
return this._updateFormatOut('jxl', options);
|
return this._updateFormatOut('jxl', options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1225,10 +1232,6 @@ function raw (options) {
|
|||||||
*
|
*
|
||||||
* The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
* The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
||||||
*
|
*
|
||||||
* Requires libvips compiled with support for libgsf.
|
|
||||||
* The prebuilt binaries do not include this - see
|
|
||||||
* {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
|
|
||||||
*
|
|
||||||
* @example
|
* @example
|
||||||
* sharp('input.tiff')
|
* sharp('input.tiff')
|
||||||
* .png()
|
* .png()
|
||||||
@@ -1549,6 +1552,7 @@ function _pipeline (callback, stack) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with output-related functions.
|
* Decorate the Sharp prototype with output-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ const kernel = {
|
|||||||
cubic: 'cubic',
|
cubic: 'cubic',
|
||||||
mitchell: 'mitchell',
|
mitchell: 'mitchell',
|
||||||
lanczos2: 'lanczos2',
|
lanczos2: 'lanczos2',
|
||||||
lanczos3: 'lanczos3'
|
lanczos3: 'lanczos3',
|
||||||
|
mks2013: 'mks2013',
|
||||||
|
mks2021: 'mks2021'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -569,6 +571,7 @@ function trim (options) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp prototype with resize-related functions.
|
* Decorate the Sharp prototype with resize-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ if (sharp) {
|
|||||||
help.push(
|
help.push(
|
||||||
'- Ensure optional dependencies can be installed:',
|
'- Ensure optional dependencies can be installed:',
|
||||||
' npm install --include=optional sharp',
|
' npm install --include=optional sharp',
|
||||||
' yarn add sharp --ignore-engines',
|
|
||||||
'- Ensure your package manager supports multi-platform installation:',
|
'- Ensure your package manager supports multi-platform installation:',
|
||||||
' See https://sharp.pixelplumbing.com/install#cross-platform',
|
' See https://sharp.pixelplumbing.com/install#cross-platform',
|
||||||
'- Add platform-specific dependencies:',
|
'- Add platform-specific dependencies:',
|
||||||
@@ -73,9 +72,9 @@ if (sharp) {
|
|||||||
}
|
}
|
||||||
if (isLinux && /(symbol not found|CXXABI_)/i.test(messages)) {
|
if (isLinux && /(symbol not found|CXXABI_)/i.test(messages)) {
|
||||||
try {
|
try {
|
||||||
const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
|
const { config } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
|
||||||
const libcFound = `${familySync()} ${versionSync()}`;
|
const libcFound = `${familySync()} ${versionSync()}`;
|
||||||
const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
|
const libcRequires = `${config.musl ? 'musl' : 'glibc'} ${config.musl || config.glibc}`;
|
||||||
help.push(
|
help.push(
|
||||||
'- Update your OS:',
|
'- Update your OS:',
|
||||||
` Found ${libcFound}`,
|
` Found ${libcFound}`,
|
||||||
|
|||||||
@@ -75,6 +75,13 @@ if (!libvipsVersion.isGlobal) {
|
|||||||
}
|
}
|
||||||
versions.sharp = require('../package.json').version;
|
versions.sharp = require('../package.json').version;
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (versions.heif && format.heif) {
|
||||||
|
// Prebuilt binaries provide AV1
|
||||||
|
format.heif.input.fileSuffix = ['.avif'];
|
||||||
|
format.heif.output.alias = ['avif'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
* Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
||||||
* Existing entries in the cache will be trimmed after any change in limits.
|
* Existing entries in the cache will be trimmed after any change in limits.
|
||||||
@@ -273,6 +280,7 @@ function unblock (options) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorate the Sharp class with utility-related functions.
|
* Decorate the Sharp class with utility-related functions.
|
||||||
|
* @module Sharp
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
module.exports = function (Sharp) {
|
module.exports = function (Sharp) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-darwin-arm64",
|
"name": "@img/sharp-darwin-arm64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"description": "Prebuilt sharp for use with macOS 64-bit ARM",
|
"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",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-darwin-arm64": "1.0.2"
|
"@img/sharp-libvips-darwin-arm64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,11 +29,7 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
|
||||||
"yarn": ">=3.2.0",
|
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"glibc": ">=2.26"
|
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-darwin-x64",
|
"name": "@img/sharp-darwin-x64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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": "1.0.2"
|
"@img/sharp-libvips-darwin-x64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,11 +29,7 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
|
||||||
"yarn": ">=3.2.0",
|
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"glibc": ">=2.26"
|
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-arm",
|
"name": "@img/sharp-linux-arm",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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": "1.0.2"
|
"@img/sharp-libvips-linux-arm": "1.1.0-rc3.1"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,11 +29,10 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
"glibc": ">=2.31"
|
||||||
"glibc": ">=2.28"
|
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-arm64",
|
"name": "@img/sharp-linux-arm64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"description": "Prebuilt sharp for use with Linux (glibc) 64-bit ARM",
|
"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",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linux-arm64": "1.0.2"
|
"@img/sharp-libvips-linux-arm64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,10 +29,9 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"glibc": ">=2.26"
|
"glibc": ">=2.26"
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
46
npm/linux-ppc64/package.json
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "@img/sharp-linux-ppc64",
|
||||||
|
"version": "0.33.5",
|
||||||
|
"description": "Prebuilt sharp for use with Linux (glibc) ppc64",
|
||||||
|
"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-ppc64"
|
||||||
|
},
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"preferUnplugged": true,
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-ppc64": "1.1.0-rc3"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"type": "commonjs",
|
||||||
|
"exports": {
|
||||||
|
"./sharp.node": "./lib/sharp-linux-ppc64.node",
|
||||||
|
"./package": "./package.json"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"glibc": ">=2.31"
|
||||||
|
},
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-s390x",
|
"name": "@img/sharp-linux-s390x",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"description": "Prebuilt sharp for use with Linux (glibc) s390x",
|
"description": "Prebuilt sharp for use with Linux (glibc) s390x",
|
||||||
"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-s390x": "1.0.2"
|
"@img/sharp-libvips-linux-s390x": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,10 +29,9 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"glibc": ">=2.31"
|
"glibc": ">=2.31"
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linux-x64",
|
"name": "@img/sharp-linux-x64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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": "1.0.2"
|
"@img/sharp-libvips-linux-x64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,10 +29,9 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"glibc": ">=2.26"
|
"glibc": ">=2.26"
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linuxmusl-arm64",
|
"name": "@img/sharp-linuxmusl-arm64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"description": "Prebuilt sharp for use with Linux (musl) 64-bit ARM",
|
"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",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": "1.0.2"
|
"@img/sharp-libvips-linuxmusl-arm64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,10 +29,9 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"musl": ">=1.2.2"
|
"musl": ">=1.2.2"
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-linuxmusl-x64",
|
"name": "@img/sharp-linuxmusl-x64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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": "1.0.2"
|
"@img/sharp-libvips-linuxmusl-x64": "1.1.0-rc3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
@@ -29,10 +29,9 @@
|
|||||||
"./package": "./package.json"
|
"./package": "./package.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
},
|
||||||
"yarn": ">=3.2.0",
|
"config": {
|
||||||
"pnpm": ">=7.1.0",
|
|
||||||
"musl": ">=1.2.2"
|
"musl": ">=1.2.2"
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp",
|
"name": "@img/sharp",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"darwin-arm64",
|
"darwin-arm64",
|
||||||
"darwin-x64",
|
"darwin-x64",
|
||||||
"linux-arm",
|
"linux-arm",
|
||||||
"linux-arm64",
|
"linux-arm64",
|
||||||
|
"linux-ppc64",
|
||||||
"linux-s390x",
|
"linux-s390x",
|
||||||
"linux-x64",
|
"linux-x64",
|
||||||
"linuxmusl-arm64",
|
"linuxmusl-arm64",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-wasm32",
|
"name": "@img/sharp-wasm32",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"description": "Prebuilt sharp for use with wasm32",
|
"description": "Prebuilt sharp for use with wasm32",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
@@ -28,13 +28,10 @@
|
|||||||
"./versions": "./versions.json"
|
"./versions": "./versions.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
|
||||||
"yarn": ">=3.2.0",
|
|
||||||
"pnpm": ">=7.1.0"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emnapi/runtime": "^1.1.1"
|
"@emnapi/runtime": "^1.3.1"
|
||||||
},
|
},
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"wasm32"
|
"wasm32"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-win32-ia32",
|
"name": "@img/sharp-win32-ia32",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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",
|
||||||
@@ -28,10 +28,7 @@
|
|||||||
"./versions": "./versions.json"
|
"./versions": "./versions.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
|
||||||
"yarn": ">=3.2.0",
|
|
||||||
"pnpm": ">=7.1.0"
|
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@img/sharp-win32-x64",
|
"name": "@img/sharp-win32-x64",
|
||||||
"version": "0.33.4",
|
"version": "0.33.5",
|
||||||
"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",
|
||||||
@@ -28,10 +28,7 @@
|
|||||||
"./versions": "./versions.json"
|
"./versions": "./versions.json"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
"npm": ">=9.6.5",
|
|
||||||
"yarn": ">=3.2.0",
|
|
||||||
"pnpm": ">=7.1.0"
|
|
||||||
},
|
},
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
|
|||||||
75
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.4",
|
"version": "0.33.5",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://sharp.pixelplumbing.com",
|
"homepage": "https://sharp.pixelplumbing.com",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -88,7 +88,8 @@
|
|||||||
"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>",
|
"Dennis Beatty <dennis@dcbeatty.com>",
|
||||||
"Ingvar Stepanyan <me@rreverser.com>"
|
"Ingvar Stepanyan <me@rreverser.com>",
|
||||||
|
"Don Denton <don@happycollision.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "node install/check",
|
"install": "node install/check",
|
||||||
@@ -138,56 +139,58 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"detect-libc": "^2.0.3",
|
"detect-libc": "^2.0.3",
|
||||||
"semver": "^7.6.0"
|
"semver": "^7.6.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-darwin-arm64": "0.33.4",
|
"@img/sharp-darwin-arm64": "0.33.5",
|
||||||
"@img/sharp-darwin-x64": "0.33.4",
|
"@img/sharp-darwin-x64": "0.33.5",
|
||||||
"@img/sharp-libvips-darwin-arm64": "1.0.2",
|
"@img/sharp-libvips-darwin-arm64": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-darwin-x64": "1.0.2",
|
"@img/sharp-libvips-darwin-x64": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-linux-arm": "1.0.2",
|
"@img/sharp-libvips-linux-arm": "1.1.0-rc3.1",
|
||||||
"@img/sharp-libvips-linux-arm64": "1.0.2",
|
"@img/sharp-libvips-linux-arm64": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-linux-s390x": "1.0.2",
|
"@img/sharp-libvips-linux-ppc64": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-linux-x64": "1.0.2",
|
"@img/sharp-libvips-linux-s390x": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": "1.0.2",
|
"@img/sharp-libvips-linux-x64": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-linuxmusl-x64": "1.0.2",
|
"@img/sharp-libvips-linuxmusl-arm64": "1.1.0-rc3",
|
||||||
"@img/sharp-linux-arm": "0.33.4",
|
"@img/sharp-libvips-linuxmusl-x64": "1.1.0-rc3",
|
||||||
"@img/sharp-linux-arm64": "0.33.4",
|
"@img/sharp-linux-arm": "0.33.5",
|
||||||
"@img/sharp-linux-s390x": "0.33.4",
|
"@img/sharp-linux-arm64": "0.33.5",
|
||||||
"@img/sharp-linux-x64": "0.33.4",
|
"@img/sharp-linux-s390x": "0.33.5",
|
||||||
"@img/sharp-linuxmusl-arm64": "0.33.4",
|
"@img/sharp-linux-x64": "0.33.5",
|
||||||
"@img/sharp-linuxmusl-x64": "0.33.4",
|
"@img/sharp-linuxmusl-arm64": "0.33.5",
|
||||||
"@img/sharp-wasm32": "0.33.4",
|
"@img/sharp-linuxmusl-x64": "0.33.5",
|
||||||
"@img/sharp-win32-ia32": "0.33.4",
|
"@img/sharp-wasm32": "0.33.5",
|
||||||
"@img/sharp-win32-x64": "0.33.4"
|
"@img/sharp-win32-ia32": "0.33.5",
|
||||||
|
"@img/sharp-win32-x64": "0.33.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@emnapi/runtime": "^1.1.1",
|
"@emnapi/runtime": "^1.3.1",
|
||||||
"@img/sharp-libvips-dev": "1.0.2",
|
"@img/sharp-libvips-dev": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-dev-wasm32": "1.0.3",
|
"@img/sharp-libvips-dev-wasm32": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-win32-ia32": "1.0.2",
|
"@img/sharp-libvips-win32-ia32": "1.1.0-rc3",
|
||||||
"@img/sharp-libvips-win32-x64": "1.0.2",
|
"@img/sharp-libvips-win32-x64": "1.1.0-rc3",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"async": "^3.2.5",
|
|
||||||
"cc": "^3.0.1",
|
"cc": "^3.0.1",
|
||||||
"emnapi": "^1.1.1",
|
"emnapi": "^1.3.1",
|
||||||
"exif-reader": "^2.0.1",
|
"exif-reader": "^2.0.1",
|
||||||
"extract-zip": "^2.0.1",
|
"extract-zip": "^2.0.1",
|
||||||
"icc": "^3.0.0",
|
"icc": "^3.0.0",
|
||||||
"jsdoc-to-markdown": "^8.0.1",
|
"jsdoc-to-markdown": "^9.1.1",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"mocha": "^10.4.0",
|
"mocha": "^11.0.1",
|
||||||
"node-addon-api": "^8.0.0",
|
"node-addon-api": "^8.3.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^17.1.0",
|
||||||
"prebuild": "^13.0.1",
|
"prebuild": "^13.0.1",
|
||||||
"semistandard": "^17.0.0",
|
"semistandard": "^17.0.0",
|
||||||
"tar-fs": "^3.0.6",
|
"tar-fs": "^3.0.6",
|
||||||
"tsd": "^0.31.0"
|
"tsd": "^0.31.2"
|
||||||
},
|
},
|
||||||
"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.15.2"
|
},
|
||||||
|
"config": {
|
||||||
|
"libvips": ">=8.16.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/libvips"
|
"url": "https://opencollective.com/libvips"
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
|
'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
|
||||||
},
|
},
|
||||||
'targets': [{
|
'targets': [{
|
||||||
'target_name': 'libvips-cpp',
|
'target_name': 'libvips-cpp-<(vips_version)',
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
|
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
|
||||||
'type': 'shared_library',
|
'type': 'shared_library',
|
||||||
'defines': [
|
'defines': [
|
||||||
'VIPS_CPLUSPLUS_EXPORTS',
|
'_VIPS_PUBLIC=__declspec(dllexport)',
|
||||||
'_ALLOW_KEYWORD_MACROS'
|
'_ALLOW_KEYWORD_MACROS'
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
@@ -45,6 +45,9 @@
|
|||||||
'Release': {
|
'Release': {
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCCLCompilerTool': {
|
'VCCLCompilerTool': {
|
||||||
|
"AdditionalOptions": [
|
||||||
|
"/std:c++17"
|
||||||
|
],
|
||||||
'ExceptionHandling': 1,
|
'ExceptionHandling': 1,
|
||||||
'Optimization': 1,
|
'Optimization': 1,
|
||||||
'WholeProgramOptimization': 'true'
|
'WholeProgramOptimization': 'true'
|
||||||
@@ -83,7 +86,7 @@
|
|||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<!(node -p "require(\'node-addon-api\').gyp")',
|
'<!(node -p "require(\'node-addon-api\').gyp")',
|
||||||
'libvips-cpp'
|
'libvips-cpp-<(vips_version)'
|
||||||
],
|
],
|
||||||
'variables': {
|
'variables': {
|
||||||
'conditions': [
|
'conditions': [
|
||||||
@@ -149,7 +152,7 @@
|
|||||||
['OS == "mac"', {
|
['OS == "mac"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips-cpp.42.dylib'
|
'libvips-cpp.<(vips_version).dylib'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
@@ -169,9 +172,10 @@
|
|||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'-l:libvips-cpp.so.42'
|
'-l:libvips-cpp.so.<(vips_version)'
|
||||||
],
|
],
|
||||||
'ldflags': [
|
'ldflags': [
|
||||||
|
'-lstdc++fs',
|
||||||
'-Wl,-s',
|
'-Wl,-s',
|
||||||
'-Wl,--disable-new-dtags',
|
'-Wl,--disable-new-dtags',
|
||||||
'-Wl,-z,nodelete',
|
'-Wl,-z,nodelete',
|
||||||
@@ -192,7 +196,7 @@
|
|||||||
'-Oz',
|
'-Oz',
|
||||||
'-sALLOW_MEMORY_GROWTH',
|
'-sALLOW_MEMORY_GROWTH',
|
||||||
'-sENVIRONMENT=node',
|
'-sENVIRONMENT=node',
|
||||||
'-sEXPORTED_FUNCTIONS=["_vips_shutdown", "_uv_library_shutdown"]',
|
'-sEXPORTED_FUNCTIONS=["emnapiInit", "_vips_shutdown", "_uv_library_shutdown"]',
|
||||||
'-sNODERAWFS',
|
'-sNODERAWFS',
|
||||||
'-sTEXTDECODER=0',
|
'-sTEXTDECODER=0',
|
||||||
'-sWASM_ASYNC_COMPILATION=0',
|
'-sWASM_ASYNC_COMPILATION=0',
|
||||||
@@ -207,14 +211,14 @@
|
|||||||
}]
|
}]
|
||||||
],
|
],
|
||||||
'cflags_cc': [
|
'cflags_cc': [
|
||||||
'-std=c++0x',
|
'-std=c++17',
|
||||||
'-fexceptions',
|
'-fexceptions',
|
||||||
'-Wall',
|
'-Wall',
|
||||||
'-Os'
|
'-Os'
|
||||||
],
|
],
|
||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
|
'CLANG_CXX_LANGUAGE_STANDARD': 'c++17',
|
||||||
'MACOSX_DEPLOYMENT_TARGET': '10.13',
|
'MACOSX_DEPLOYMENT_TARGET': '10.15',
|
||||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
||||||
'GCC_ENABLE_CPP_RTTI': 'YES',
|
'GCC_ENABLE_CPP_RTTI': 'YES',
|
||||||
'OTHER_CPLUSPLUSFLAGS': [
|
'OTHER_CPLUSPLUSFLAGS': [
|
||||||
@@ -234,6 +238,9 @@
|
|||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCCLCompilerTool': {
|
'VCCLCompilerTool': {
|
||||||
|
"AdditionalOptions": [
|
||||||
|
"/std:c++17"
|
||||||
|
],
|
||||||
'ExceptionHandling': 1,
|
'ExceptionHandling': 1,
|
||||||
'Optimization': 1,
|
'Optimization': 1,
|
||||||
'WholeProgramOptimization': 'true'
|
'WholeProgramOptimization': 'true'
|
||||||
|
|||||||
@@ -109,6 +109,10 @@ namespace sharp {
|
|||||||
if (HasAttr(input, "subifd")) {
|
if (HasAttr(input, "subifd")) {
|
||||||
descriptor->subifd = AttrAsInt32(input, "subifd");
|
descriptor->subifd = AttrAsInt32(input, "subifd");
|
||||||
}
|
}
|
||||||
|
// // PDF background color
|
||||||
|
if (HasAttr(input, "pdfBackground")) {
|
||||||
|
descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");
|
||||||
|
}
|
||||||
// Create new image
|
// Create new image
|
||||||
if (HasAttr(input, "createChannels")) {
|
if (HasAttr(input, "createChannels")) {
|
||||||
descriptor->createChannels = AttrAsUint32(input, "createChannels");
|
descriptor->createChannels = AttrAsUint32(input, "createChannels");
|
||||||
@@ -402,6 +406,9 @@ namespace sharp {
|
|||||||
if (imageType == ImageType::TIFF) {
|
if (imageType == ImageType::TIFF) {
|
||||||
option->set("subifd", descriptor->subifd);
|
option->set("subifd", descriptor->subifd);
|
||||||
}
|
}
|
||||||
|
if (imageType == ImageType::PDF) {
|
||||||
|
option->set("background", descriptor->pdfBackground);
|
||||||
|
}
|
||||||
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
||||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
||||||
image = SetDensity(image, descriptor->density);
|
image = SetDensity(image, descriptor->density);
|
||||||
@@ -506,6 +513,9 @@ namespace sharp {
|
|||||||
if (imageType == ImageType::TIFF) {
|
if (imageType == ImageType::TIFF) {
|
||||||
option->set("subifd", descriptor->subifd);
|
option->set("subifd", descriptor->subifd);
|
||||||
}
|
}
|
||||||
|
if (imageType == ImageType::PDF) {
|
||||||
|
option->set("background", descriptor->pdfBackground);
|
||||||
|
}
|
||||||
image = VImage::new_from_file(descriptor->file.data(), option);
|
image = VImage::new_from_file(descriptor->file.data(), option);
|
||||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
||||||
image = SetDensity(image, descriptor->density);
|
image = SetDensity(image, descriptor->density);
|
||||||
|
|||||||
20
src/common.h
@@ -15,18 +15,14 @@
|
|||||||
// 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 < 15) || \
|
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 16) || \
|
||||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 2)
|
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 16 && VIPS_MICRO_VERSION < 0)
|
||||||
#error "libvips version 8.15.2+ is required - please see https://sharp.pixelplumbing.com/install"
|
#error "libvips version 8.16.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(__has_include)
|
||||||
#error "GCC version 4.6+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
|
#if !__has_include(<filesystem>)
|
||||||
#endif
|
#error "C++17 compiler required - please see https://sharp.pixelplumbing.com/install"
|
||||||
|
|
||||||
#if (defined(__clang__) && defined(__has_feature))
|
|
||||||
#if (!__has_feature(cxx_range_for))
|
|
||||||
#error "clang version 3.0+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -74,6 +70,7 @@ namespace sharp {
|
|||||||
int textSpacing;
|
int textSpacing;
|
||||||
VipsTextWrap textWrap;
|
VipsTextWrap textWrap;
|
||||||
int textAutofitDpi;
|
int textAutofitDpi;
|
||||||
|
std::vector<double> pdfBackground;
|
||||||
|
|
||||||
InputDescriptor():
|
InputDescriptor():
|
||||||
buffer(nullptr),
|
buffer(nullptr),
|
||||||
@@ -108,7 +105,8 @@ namespace sharp {
|
|||||||
textRgba(false),
|
textRgba(false),
|
||||||
textSpacing(0),
|
textSpacing(0),
|
||||||
textWrap(VIPS_TEXT_WRAP_WORD),
|
textWrap(VIPS_TEXT_WRAP_WORD),
|
||||||
textAutofitDpi(0) {}
|
textAutofitDpi(0),
|
||||||
|
pdfBackground{ 255.0, 255.0, 255.0, 255.0 } {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience methods to access the attributes of a Napi::Object
|
// Convenience methods to access the attributes of a Napi::Object
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
'default_configuration': 'Release',
|
'default_configuration': 'Release',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
'cflags': [
|
'cflags': [
|
||||||
'-pthread',
|
'-pthread'
|
||||||
'-sDEFAULT_TO_CXX=0'
|
|
||||||
],
|
],
|
||||||
'cflags_cc': [
|
'cflags_cc': [
|
||||||
'-pthread'
|
'-pthread'
|
||||||
@@ -19,6 +18,7 @@
|
|||||||
'--js-library=<!(node -p "require(\'emnapi\').js_library")',
|
'--js-library=<!(node -p "require(\'emnapi\').js_library")',
|
||||||
'-sAUTO_JS_LIBRARIES=0',
|
'-sAUTO_JS_LIBRARIES=0',
|
||||||
'-sAUTO_NATIVE_LIBRARIES=0',
|
'-sAUTO_NATIVE_LIBRARIES=0',
|
||||||
|
'-sDEFAULT_TO_CXX=0',
|
||||||
'-sNODEJS_CATCH_EXIT=0',
|
'-sNODEJS_CATCH_EXIT=0',
|
||||||
'-sNODEJS_CATCH_REJECTION=0'
|
'-sNODEJS_CATCH_REJECTION=0'
|
||||||
],
|
],
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
'EMNAPI_WORKER_POOL_SIZE=1'
|
'EMNAPI_WORKER_POOL_SIZE=1'
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'<!(node -p "require(\'emnapi\').include")'
|
'<!(node -p "require(\'emnapi\').include_dir")'
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'<!@(node -p "require(\'emnapi\').sources.map(x => JSON.stringify(path.relative(process.cwd(), x))).join(\' \')")'
|
'<!@(node -p "require(\'emnapi\').sources.map(x => JSON.stringify(path.relative(process.cwd(), x))).join(\' \')")'
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <napi.h>
|
#include <napi.h>
|
||||||
#include <vips/vips8>
|
#include <vips/vips8>
|
||||||
@@ -10,6 +11,8 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
|
|
||||||
|
static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p);
|
||||||
|
|
||||||
class MetadataWorker : public Napi::AsyncWorker {
|
class MetadataWorker : public Napi::AsyncWorker {
|
||||||
public:
|
public:
|
||||||
MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) :
|
MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) :
|
||||||
@@ -45,8 +48,11 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
if (image.get_typeof("interlaced") == G_TYPE_INT) {
|
if (image.get_typeof("interlaced") == G_TYPE_INT) {
|
||||||
baton->isProgressive = image.get_int("interlaced") == 1;
|
baton->isProgressive = image.get_int("interlaced") == 1;
|
||||||
}
|
}
|
||||||
if (image.get_typeof("palette-bit-depth") == G_TYPE_INT) {
|
if (image.get_typeof(VIPS_META_PALETTE) == G_TYPE_INT) {
|
||||||
baton->paletteBitDepth = image.get_int("palette-bit-depth");
|
baton->isPalette = image.get_int(VIPS_META_PALETTE);
|
||||||
|
}
|
||||||
|
if (image.get_typeof(VIPS_META_BITS_PER_SAMPLE) == G_TYPE_INT) {
|
||||||
|
baton->bitsPerSample = image.get_int(VIPS_META_BITS_PER_SAMPLE);
|
||||||
}
|
}
|
||||||
if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
|
if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
|
||||||
baton->pages = image.get_int(VIPS_META_N_PAGES);
|
baton->pages = image.get_int(VIPS_META_N_PAGES);
|
||||||
@@ -131,6 +137,8 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
|
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
|
||||||
baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
|
baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
|
||||||
}
|
}
|
||||||
|
// PNG comments
|
||||||
|
vips_image_map(image.get_image(), readPNGComment, &baton->comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
@@ -167,8 +175,13 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
info.Set("chromaSubsampling", baton->chromaSubsampling);
|
info.Set("chromaSubsampling", baton->chromaSubsampling);
|
||||||
}
|
}
|
||||||
info.Set("isProgressive", baton->isProgressive);
|
info.Set("isProgressive", baton->isProgressive);
|
||||||
if (baton->paletteBitDepth > 0) {
|
info.Set("isPalette", baton->isPalette);
|
||||||
info.Set("paletteBitDepth", baton->paletteBitDepth);
|
if (baton->bitsPerSample > 0) {
|
||||||
|
info.Set("bitsPerSample", baton->bitsPerSample);
|
||||||
|
if (baton->isPalette) {
|
||||||
|
// Deprecated, remove with libvips 8.17.0
|
||||||
|
info.Set("paletteBitDepth", baton->bitsPerSample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (baton->pages > 0) {
|
if (baton->pages > 0) {
|
||||||
info.Set("pages", baton->pages);
|
info.Set("pages", baton->pages);
|
||||||
@@ -214,15 +227,15 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
info.Set("subifds", baton->subifds);
|
info.Set("subifds", baton->subifds);
|
||||||
}
|
}
|
||||||
if (!baton->background.empty()) {
|
if (!baton->background.empty()) {
|
||||||
|
Napi::Object background = Napi::Object::New(env);
|
||||||
if (baton->background.size() == 3) {
|
if (baton->background.size() == 3) {
|
||||||
Napi::Object background = Napi::Object::New(env);
|
|
||||||
background.Set("r", baton->background[0]);
|
background.Set("r", baton->background[0]);
|
||||||
background.Set("g", baton->background[1]);
|
background.Set("g", baton->background[1]);
|
||||||
background.Set("b", baton->background[2]);
|
background.Set("b", baton->background[2]);
|
||||||
info.Set("background", background);
|
|
||||||
} else {
|
} else {
|
||||||
info.Set("background", baton->background[0]);
|
background.Set("gray", round(baton->background[0] * 100 / 255));
|
||||||
}
|
}
|
||||||
|
info.Set("background", background);
|
||||||
}
|
}
|
||||||
info.Set("hasProfile", baton->hasProfile);
|
info.Set("hasProfile", baton->hasProfile);
|
||||||
info.Set("hasAlpha", baton->hasAlpha);
|
info.Set("hasAlpha", baton->hasAlpha);
|
||||||
@@ -246,6 +259,17 @@ 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));
|
||||||
}
|
}
|
||||||
|
if (baton->comments.size() > 0) {
|
||||||
|
int i = 0;
|
||||||
|
Napi::Array comments = Napi::Array::New(env, baton->comments.size());
|
||||||
|
for (auto &c : baton->comments) {
|
||||||
|
Napi::Object comment = Napi::Object::New(env);
|
||||||
|
comment.Set("keyword", c.first);
|
||||||
|
comment.Set("text", c.second);
|
||||||
|
comments.Set(i++, comment);
|
||||||
|
}
|
||||||
|
info.Set("comments", comments);
|
||||||
|
}
|
||||||
Callback().Call(Receiver().Value(), { env.Null(), info });
|
Callback().Call(Receiver().Value(), { env.Null(), info });
|
||||||
} else {
|
} else {
|
||||||
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
||||||
@@ -285,3 +309,21 @@ Napi::Value metadata(const Napi::CallbackInfo& info) {
|
|||||||
|
|
||||||
return info.Env().Undefined();
|
return info.Env().Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *PNG_COMMENT_START = "png-comment-";
|
||||||
|
const int PNG_COMMENT_START_LEN = strlen(PNG_COMMENT_START);
|
||||||
|
|
||||||
|
static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p) {
|
||||||
|
MetadataComments *comments = static_cast<MetadataComments *>(p);
|
||||||
|
|
||||||
|
if (vips_isprefix(PNG_COMMENT_START, field)) {
|
||||||
|
const char *keyword = strchr(field + PNG_COMMENT_START_LEN, '-');
|
||||||
|
const char *str;
|
||||||
|
if (keyword != NULL && !vips_image_get_string(image, field, &str)) {
|
||||||
|
keyword++; // Skip the hyphen
|
||||||
|
comments->push_back(std::make_pair(keyword, str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include "./common.h"
|
#include "./common.h"
|
||||||
|
|
||||||
|
typedef std::vector<std::pair<std::string, std::string>> MetadataComments;
|
||||||
|
|
||||||
struct MetadataBaton {
|
struct MetadataBaton {
|
||||||
// Input
|
// Input
|
||||||
sharp::InputDescriptor *input;
|
sharp::InputDescriptor *input;
|
||||||
@@ -22,7 +24,8 @@ struct MetadataBaton {
|
|||||||
int density;
|
int density;
|
||||||
std::string chromaSubsampling;
|
std::string chromaSubsampling;
|
||||||
bool isProgressive;
|
bool isProgressive;
|
||||||
int paletteBitDepth;
|
bool isPalette;
|
||||||
|
int bitsPerSample;
|
||||||
int pages;
|
int pages;
|
||||||
int pageHeight;
|
int pageHeight;
|
||||||
int loop;
|
int loop;
|
||||||
@@ -47,6 +50,7 @@ struct MetadataBaton {
|
|||||||
size_t xmpLength;
|
size_t xmpLength;
|
||||||
char *tifftagPhotoshop;
|
char *tifftagPhotoshop;
|
||||||
size_t tifftagPhotoshopLength;
|
size_t tifftagPhotoshopLength;
|
||||||
|
MetadataComments comments;
|
||||||
std::string err;
|
std::string err;
|
||||||
|
|
||||||
MetadataBaton():
|
MetadataBaton():
|
||||||
@@ -56,7 +60,8 @@ struct MetadataBaton {
|
|||||||
channels(0),
|
channels(0),
|
||||||
density(0),
|
density(0),
|
||||||
isProgressive(false),
|
isProgressive(false),
|
||||||
paletteBitDepth(0),
|
isPalette(false),
|
||||||
|
bitsPerSample(0),
|
||||||
pages(0),
|
pages(0),
|
||||||
pageHeight(0),
|
pageHeight(0),
|
||||||
loop(-1),
|
loop(-1),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace sharp {
|
|||||||
/*
|
/*
|
||||||
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
||||||
*/
|
*/
|
||||||
VImage Blur(VImage image, double const sigma) {
|
VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl) {
|
||||||
if (sigma == -1.0) {
|
if (sigma == -1.0) {
|
||||||
// Fast, mild blur - averages neighbouring pixels
|
// Fast, mild blur - averages neighbouring pixels
|
||||||
VImage blur = VImage::new_matrixv(3, 3,
|
VImage blur = VImage::new_matrixv(3, 3,
|
||||||
@@ -155,7 +155,9 @@ namespace sharp {
|
|||||||
return image.conv(blur);
|
return image.conv(blur);
|
||||||
} else {
|
} else {
|
||||||
// Slower, accurate Gaussian blur
|
// Slower, accurate Gaussian blur
|
||||||
return StaySequential(image).gaussblur(sigma);
|
return StaySequential(image).gaussblur(sigma, VImage::option()
|
||||||
|
->set("precision", precision)
|
||||||
|
->set("min_ampl", minAmpl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,10 +166,10 @@ namespace sharp {
|
|||||||
*/
|
*/
|
||||||
VImage Convolve(VImage image, int const width, int const height,
|
VImage Convolve(VImage image, int const width, int const height,
|
||||||
double const scale, double const offset,
|
double const scale, double const offset,
|
||||||
std::unique_ptr<double[]> const &kernel_v
|
std::vector<double> const &kernel_v
|
||||||
) {
|
) {
|
||||||
VImage kernel = VImage::new_from_memory(
|
VImage kernel = VImage::new_from_memory(
|
||||||
kernel_v.get(),
|
static_cast<void*>(const_cast<double*>(kernel_v.data())),
|
||||||
width * height * sizeof(double),
|
width * height * sizeof(double),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@@ -183,19 +185,21 @@ namespace sharp {
|
|||||||
* Recomb with a Matrix of the given bands/channel size.
|
* Recomb with a Matrix of the given bands/channel size.
|
||||||
* Eg. RGB will be a 3x3 matrix.
|
* Eg. RGB will be a 3x3 matrix.
|
||||||
*/
|
*/
|
||||||
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix) {
|
VImage Recomb(VImage image, std::vector<double> const& matrix) {
|
||||||
double *m = matrix.get();
|
double* m = const_cast<double*>(matrix.data());
|
||||||
image = image.colourspace(VIPS_INTERPRETATION_sRGB);
|
image = image.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||||
return image
|
if (matrix.size() == 9) {
|
||||||
.recomb(image.bands() == 3
|
return image
|
||||||
? VImage::new_from_memory(
|
.recomb(image.bands() == 3
|
||||||
m, 9 * sizeof(double), 3, 3, 1, VIPS_FORMAT_DOUBLE
|
? VImage::new_matrix(3, 3, m, 9)
|
||||||
)
|
: VImage::new_matrixv(4, 4,
|
||||||
: VImage::new_matrixv(4, 4,
|
m[0], m[1], m[2], 0.0,
|
||||||
m[0], m[1], m[2], 0.0,
|
m[3], m[4], m[5], 0.0,
|
||||||
m[3], m[4], m[5], 0.0,
|
m[6], m[7], m[8], 0.0,
|
||||||
m[6], m[7], m[8], 0.0,
|
0.0, 0.0, 0.0, 1.0));
|
||||||
0.0, 0.0, 0.0, 1.0));
|
} else {
|
||||||
|
return image.recomb(VImage::new_matrix(4, 4, m, 16));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VImage Modulate(VImage image, double const brightness, double const saturation,
|
VImage Modulate(VImage image, double const brightness, double const saturation,
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ namespace sharp {
|
|||||||
/*
|
/*
|
||||||
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
||||||
*/
|
*/
|
||||||
VImage Blur(VImage image, double const sigma);
|
VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convolution with a kernel.
|
* Convolution with a kernel.
|
||||||
*/
|
*/
|
||||||
VImage Convolve(VImage image, int const width, int const height,
|
VImage Convolve(VImage image, int const width, int const height,
|
||||||
double const scale, double const offset, std::unique_ptr<double[]> const &kernel_v);
|
double const scale, double const offset, std::vector<double> const &kernel_v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
||||||
@@ -95,7 +95,7 @@ namespace sharp {
|
|||||||
* Recomb with a Matrix of the given bands/channel size.
|
* Recomb with a Matrix of the given bands/channel size.
|
||||||
* Eg. RGB will be a 3x3 matrix.
|
* Eg. RGB will be a 3x3 matrix.
|
||||||
*/
|
*/
|
||||||
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix);
|
VImage Recomb(VImage image, std::vector<double> const &matrix);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modulate brightness, saturation, hue and lightness
|
* Modulate brightness, saturation, hue and lightness
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <filesystem>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -20,17 +21,6 @@
|
|||||||
#include "operations.h"
|
#include "operations.h"
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define STAT64_STRUCT __stat64
|
|
||||||
#define STAT64_FUNCTION _stat64
|
|
||||||
#elif defined(_LARGEFILE64_SOURCE)
|
|
||||||
#define STAT64_STRUCT stat64
|
|
||||||
#define STAT64_FUNCTION stat64
|
|
||||||
#else
|
|
||||||
#define STAT64_STRUCT stat
|
|
||||||
#define STAT64_FUNCTION stat
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class PipelineWorker : public Napi::AsyncWorker {
|
class PipelineWorker : public Napi::AsyncWorker {
|
||||||
public:
|
public:
|
||||||
PipelineWorker(Napi::Function callback, PipelineBaton *baton,
|
PipelineWorker(Napi::Function callback, PipelineBaton *baton,
|
||||||
@@ -325,6 +315,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->withIccProfile.empty()) {
|
if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->withIccProfile.empty()) {
|
||||||
// Cache input profile for use with output
|
// Cache input profile for use with output
|
||||||
inputProfile = sharp::GetProfile(image);
|
inputProfile = sharp::GetProfile(image);
|
||||||
|
baton->input->ignoreIcc = true;
|
||||||
}
|
}
|
||||||
char const *processingProfile = image.interpretation() == VIPS_INTERPRETATION_RGB16 ? "p3" : "srgb";
|
char const *processingProfile = image.interpretation() == VIPS_INTERPRETATION_RGB16 ? "p3" : "srgb";
|
||||||
if (
|
if (
|
||||||
@@ -592,7 +583,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
|
|
||||||
// Blur
|
// Blur
|
||||||
if (shouldBlur) {
|
if (shouldBlur) {
|
||||||
image = sharp::Blur(image, baton->blurSigma);
|
image = sharp::Blur(image, baton->blurSigma, baton->precision, baton->minAmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unflatten the image
|
// Unflatten the image
|
||||||
@@ -609,7 +600,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recomb
|
// Recomb
|
||||||
if (baton->recombMatrix != NULL) {
|
if (!baton->recombMatrix.empty()) {
|
||||||
image = sharp::Recomb(image, baton->recombMatrix);
|
image = sharp::Recomb(image, baton->recombMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,6 +840,11 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
image = sharp::SetAnimationProperties(
|
image = sharp::SetAnimationProperties(
|
||||||
image, nPages, targetPageHeight, baton->delay, baton->loop);
|
image, nPages, targetPageHeight, baton->delay, baton->loop);
|
||||||
|
|
||||||
|
if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
|
||||||
|
baton->pageHeightOut = image.get_int(VIPS_META_PAGE_HEIGHT);
|
||||||
|
baton->pagesOut = image.get_int(VIPS_META_N_PAGES);
|
||||||
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
sharp::SetTimeout(image, baton->timeoutSeconds);
|
sharp::SetTimeout(image, baton->timeoutSeconds);
|
||||||
if (baton->fileOut.empty()) {
|
if (baton->fileOut.empty()) {
|
||||||
@@ -923,6 +919,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
->set("lossless", baton->webpLossless)
|
->set("lossless", baton->webpLossless)
|
||||||
->set("near_lossless", baton->webpNearLossless)
|
->set("near_lossless", baton->webpNearLossless)
|
||||||
->set("smart_subsample", baton->webpSmartSubsample)
|
->set("smart_subsample", baton->webpSmartSubsample)
|
||||||
|
->set("smart_deblock", baton->webpSmartDeblock)
|
||||||
->set("preset", baton->webpPreset)
|
->set("preset", baton->webpPreset)
|
||||||
->set("effort", baton->webpEffort)
|
->set("effort", baton->webpEffort)
|
||||||
->set("min_size", baton->webpMinSize)
|
->set("min_size", baton->webpMinSize)
|
||||||
@@ -1130,6 +1127,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
->set("lossless", baton->webpLossless)
|
->set("lossless", baton->webpLossless)
|
||||||
->set("near_lossless", baton->webpNearLossless)
|
->set("near_lossless", baton->webpNearLossless)
|
||||||
->set("smart_subsample", baton->webpSmartSubsample)
|
->set("smart_subsample", baton->webpSmartSubsample)
|
||||||
|
->set("smart_deblock", baton->webpSmartDeblock)
|
||||||
->set("preset", baton->webpPreset)
|
->set("preset", baton->webpPreset)
|
||||||
->set("effort", baton->webpEffort)
|
->set("effort", baton->webpEffort)
|
||||||
->set("min_size", baton->webpMinSize)
|
->set("min_size", baton->webpMinSize)
|
||||||
@@ -1284,6 +1282,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
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));
|
||||||
}
|
}
|
||||||
|
if (baton->pageHeightOut) {
|
||||||
|
info.Set("pageHeight", static_cast<int32_t>(baton->pageHeightOut));
|
||||||
|
info.Set("pages", static_cast<int32_t>(baton->pagesOut));
|
||||||
|
}
|
||||||
|
|
||||||
if (baton->bufferOutLength > 0) {
|
if (baton->bufferOutLength > 0) {
|
||||||
// Add buffer size to info
|
// Add buffer size to info
|
||||||
@@ -1294,9 +1296,11 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
Callback().Call(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;
|
if (baton->formatOut != "dz" || sharp::IsDzZip(baton->fileOut)) {
|
||||||
if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
|
try {
|
||||||
info.Set("size", static_cast<uint32_t>(st.st_size));
|
uint32_t const size = static_cast<uint32_t>(std::filesystem::file_size(baton->fileOut));
|
||||||
|
info.Set("size", size);
|
||||||
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
Callback().Call(Receiver().Value(), { env.Null(), info });
|
Callback().Call(Receiver().Value(), { env.Null(), info });
|
||||||
}
|
}
|
||||||
@@ -1409,6 +1413,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
{"lossless", baton->webpLossless ? "true" : "false"},
|
{"lossless", baton->webpLossless ? "true" : "false"},
|
||||||
{"near_lossless", baton->webpNearLossless ? "true" : "false"},
|
{"near_lossless", baton->webpNearLossless ? "true" : "false"},
|
||||||
{"smart_subsample", baton->webpSmartSubsample ? "true" : "false"},
|
{"smart_subsample", baton->webpSmartSubsample ? "true" : "false"},
|
||||||
|
{"smart_deblock", baton->webpSmartDeblock ? "true" : "false"},
|
||||||
{"preset", vips_enum_nick(VIPS_TYPE_FOREIGN_WEBP_PRESET, baton->webpPreset)},
|
{"preset", vips_enum_nick(VIPS_TYPE_FOREIGN_WEBP_PRESET, baton->webpPreset)},
|
||||||
{"min_size", baton->webpMinSize ? "true" : "false"},
|
{"min_size", baton->webpMinSize ? "true" : "false"},
|
||||||
{"mixed", baton->webpMixed ? "true" : "false"},
|
{"mixed", baton->webpMixed ? "true" : "false"},
|
||||||
@@ -1532,6 +1537,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
baton->negate = sharp::AttrAsBool(options, "negate");
|
baton->negate = sharp::AttrAsBool(options, "negate");
|
||||||
baton->negateAlpha = sharp::AttrAsBool(options, "negateAlpha");
|
baton->negateAlpha = sharp::AttrAsBool(options, "negateAlpha");
|
||||||
baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
|
baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
|
||||||
|
baton->precision = sharp::AttrAsEnum<VipsPrecision>(options, "precision", VIPS_TYPE_PRECISION);
|
||||||
|
baton->minAmpl = sharp::AttrAsDouble(options, "minAmpl");
|
||||||
baton->brightness = sharp::AttrAsDouble(options, "brightness");
|
baton->brightness = sharp::AttrAsDouble(options, "brightness");
|
||||||
baton->saturation = sharp::AttrAsDouble(options, "saturation");
|
baton->saturation = sharp::AttrAsDouble(options, "saturation");
|
||||||
baton->hue = sharp::AttrAsInt32(options, "hue");
|
baton->hue = sharp::AttrAsInt32(options, "hue");
|
||||||
@@ -1597,17 +1604,18 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
baton->convKernelScale = sharp::AttrAsDouble(kernel, "scale");
|
baton->convKernelScale = sharp::AttrAsDouble(kernel, "scale");
|
||||||
baton->convKernelOffset = sharp::AttrAsDouble(kernel, "offset");
|
baton->convKernelOffset = sharp::AttrAsDouble(kernel, "offset");
|
||||||
size_t const kernelSize = static_cast<size_t>(baton->convKernelWidth * baton->convKernelHeight);
|
size_t const kernelSize = static_cast<size_t>(baton->convKernelWidth * baton->convKernelHeight);
|
||||||
baton->convKernel = std::unique_ptr<double[]>(new double[kernelSize]);
|
baton->convKernel.resize(kernelSize);
|
||||||
Napi::Array kdata = kernel.Get("kernel").As<Napi::Array>();
|
Napi::Array kdata = kernel.Get("kernel").As<Napi::Array>();
|
||||||
for (unsigned int i = 0; i < kernelSize; i++) {
|
for (unsigned int i = 0; i < kernelSize; i++) {
|
||||||
baton->convKernel[i] = sharp::AttrAsDouble(kdata, i);
|
baton->convKernel[i] = sharp::AttrAsDouble(kdata, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.Has("recombMatrix")) {
|
if (options.Has("recombMatrix")) {
|
||||||
baton->recombMatrix = std::unique_ptr<double[]>(new double[9]);
|
|
||||||
Napi::Array recombMatrix = options.Get("recombMatrix").As<Napi::Array>();
|
Napi::Array recombMatrix = options.Get("recombMatrix").As<Napi::Array>();
|
||||||
for (unsigned int i = 0; i < 9; i++) {
|
unsigned int matrixElements = recombMatrix.Length();
|
||||||
baton->recombMatrix[i] = sharp::AttrAsDouble(recombMatrix, i);
|
baton->recombMatrix.resize(matrixElements);
|
||||||
|
for (unsigned int i = 0; i < matrixElements; i++) {
|
||||||
|
baton->recombMatrix[i] = sharp::AttrAsDouble(recombMatrix, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
baton->colourspacePipeline = sharp::AttrAsEnum<VipsInterpretation>(
|
baton->colourspacePipeline = sharp::AttrAsEnum<VipsInterpretation>(
|
||||||
@@ -1663,6 +1671,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|||||||
baton->webpLossless = sharp::AttrAsBool(options, "webpLossless");
|
baton->webpLossless = sharp::AttrAsBool(options, "webpLossless");
|
||||||
baton->webpNearLossless = sharp::AttrAsBool(options, "webpNearLossless");
|
baton->webpNearLossless = sharp::AttrAsBool(options, "webpNearLossless");
|
||||||
baton->webpSmartSubsample = sharp::AttrAsBool(options, "webpSmartSubsample");
|
baton->webpSmartSubsample = sharp::AttrAsBool(options, "webpSmartSubsample");
|
||||||
|
baton->webpSmartDeblock = sharp::AttrAsBool(options, "webpSmartDeblock");
|
||||||
baton->webpPreset = sharp::AttrAsEnum<VipsForeignWebpPreset>(options, "webpPreset", VIPS_TYPE_FOREIGN_WEBP_PRESET);
|
baton->webpPreset = sharp::AttrAsEnum<VipsForeignWebpPreset>(options, "webpPreset", VIPS_TYPE_FOREIGN_WEBP_PRESET);
|
||||||
baton->webpEffort = sharp::AttrAsUint32(options, "webpEffort");
|
baton->webpEffort = sharp::AttrAsUint32(options, "webpEffort");
|
||||||
baton->webpMinSize = sharp::AttrAsBool(options, "webpMinSize");
|
baton->webpMinSize = sharp::AttrAsBool(options, "webpMinSize");
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ struct PipelineBaton {
|
|||||||
std::string fileOut;
|
std::string fileOut;
|
||||||
void *bufferOut;
|
void *bufferOut;
|
||||||
size_t bufferOutLength;
|
size_t bufferOutLength;
|
||||||
|
int pageHeightOut;
|
||||||
|
int pagesOut;
|
||||||
std::vector<Composite *> composite;
|
std::vector<Composite *> composite;
|
||||||
std::vector<sharp::InputDescriptor *> joinChannelIn;
|
std::vector<sharp::InputDescriptor *> joinChannelIn;
|
||||||
int topOffsetPre;
|
int topOffsetPre;
|
||||||
@@ -76,6 +78,8 @@ struct PipelineBaton {
|
|||||||
bool negate;
|
bool negate;
|
||||||
bool negateAlpha;
|
bool negateAlpha;
|
||||||
double blurSigma;
|
double blurSigma;
|
||||||
|
VipsPrecision precision;
|
||||||
|
double minAmpl;
|
||||||
double brightness;
|
double brightness;
|
||||||
double saturation;
|
double saturation;
|
||||||
int hue;
|
int hue;
|
||||||
@@ -153,6 +157,7 @@ struct PipelineBaton {
|
|||||||
bool webpNearLossless;
|
bool webpNearLossless;
|
||||||
bool webpLossless;
|
bool webpLossless;
|
||||||
bool webpSmartSubsample;
|
bool webpSmartSubsample;
|
||||||
|
bool webpSmartDeblock;
|
||||||
VipsForeignWebpPreset webpPreset;
|
VipsForeignWebpPreset webpPreset;
|
||||||
int webpEffort;
|
int webpEffort;
|
||||||
bool webpMinSize;
|
bool webpMinSize;
|
||||||
@@ -195,7 +200,7 @@ struct PipelineBaton {
|
|||||||
std::unordered_map<std::string, std::string> withExif;
|
std::unordered_map<std::string, std::string> withExif;
|
||||||
bool withExifMerge;
|
bool withExifMerge;
|
||||||
int timeoutSeconds;
|
int timeoutSeconds;
|
||||||
std::unique_ptr<double[]> convKernel;
|
std::vector<double> convKernel;
|
||||||
int convKernelWidth;
|
int convKernelWidth;
|
||||||
int convKernelHeight;
|
int convKernelHeight;
|
||||||
double convKernelScale;
|
double convKernelScale;
|
||||||
@@ -221,11 +226,13 @@ struct PipelineBaton {
|
|||||||
VipsForeignDzDepth tileDepth;
|
VipsForeignDzDepth tileDepth;
|
||||||
std::string tileId;
|
std::string tileId;
|
||||||
std::string tileBasename;
|
std::string tileBasename;
|
||||||
std::unique_ptr<double[]> recombMatrix;
|
std::vector<double> recombMatrix;
|
||||||
|
|
||||||
PipelineBaton():
|
PipelineBaton():
|
||||||
input(nullptr),
|
input(nullptr),
|
||||||
bufferOutLength(0),
|
bufferOutLength(0),
|
||||||
|
pageHeightOut(0),
|
||||||
|
pagesOut(0),
|
||||||
topOffsetPre(-1),
|
topOffsetPre(-1),
|
||||||
topOffsetPost(-1),
|
topOffsetPost(-1),
|
||||||
channels(0),
|
channels(0),
|
||||||
@@ -322,6 +329,7 @@ struct PipelineBaton {
|
|||||||
webpNearLossless(false),
|
webpNearLossless(false),
|
||||||
webpLossless(false),
|
webpLossless(false),
|
||||||
webpSmartSubsample(false),
|
webpSmartSubsample(false),
|
||||||
|
webpSmartDeblock(false),
|
||||||
webpPreset(VIPS_FOREIGN_WEBP_PRESET_DEFAULT),
|
webpPreset(VIPS_FOREIGN_WEBP_PRESET_DEFAULT),
|
||||||
webpEffort(4),
|
webpEffort(4),
|
||||||
webpMinSize(false),
|
webpMinSize(false),
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ const width = 720;
|
|||||||
const height = 480;
|
const height = 480;
|
||||||
|
|
||||||
sharp.concurrency(1);
|
sharp.concurrency(1);
|
||||||
sharp.simd(true);
|
|
||||||
|
|
||||||
const timer = setInterval(function () {
|
const timer = setInterval(function () {
|
||||||
console.dir(sharp.counters());
|
console.dir(sharp.counters());
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ const sharp = require('../../');
|
|||||||
const fixtures = require('../fixtures');
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
sharp.cache(false);
|
sharp.cache(false);
|
||||||
sharp.simd(true);
|
|
||||||
|
|
||||||
const min = 320;
|
const min = 320;
|
||||||
const max = 960;
|
const max = 960;
|
||||||
|
|||||||
BIN
test/fixtures/bgbn4a08.png
vendored
Normal file
|
After Width: | Height: | Size: 140 B |
BIN
test/fixtures/bggn4a16.png
vendored
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
test/fixtures/d.png
vendored
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
test/fixtures/expected/d-opacity-30.png
vendored
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
test/fixtures/expected/flip-and-flop.jpg
vendored
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
BIN
test/fixtures/expected/gravity-center-width.webp
vendored
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 9.3 KiB |
BIN
test/fixtures/expected/tint-blue.jpg
vendored
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
test/fixtures/expected/tint-cmyk.jpg
vendored
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
BIN
test/fixtures/expected/tint-green.jpg
vendored
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
test/fixtures/expected/tint-red.jpg
vendored
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
test/fixtures/expected/tint-sepia.jpg
vendored
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
test/fixtures/expected/webp-alpha-80.webp
vendored
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 152 KiB |
81
test/fixtures/index.js
vendored
@@ -14,29 +14,26 @@ const getPath = function (filename) {
|
|||||||
|
|
||||||
// Generates a 64-bit-as-binary-string image fingerprint
|
// Generates a 64-bit-as-binary-string image fingerprint
|
||||||
// Based on the dHash gradient method - see http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
|
// Based on the dHash gradient method - see http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
|
||||||
const fingerprint = function (image, callback) {
|
async function fingerprint (image) {
|
||||||
sharp(image)
|
return sharp(image)
|
||||||
.flatten('gray')
|
.flatten('gray')
|
||||||
.greyscale()
|
.greyscale()
|
||||||
.normalise()
|
.normalise()
|
||||||
.resize(9, 8, { fit: sharp.fit.fill })
|
.resize(9, 8, { fit: sharp.fit.fill })
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer(function (err, data) {
|
.toBuffer()
|
||||||
if (err) {
|
.then(function (data) {
|
||||||
callback(err);
|
let fingerprint = '';
|
||||||
} else {
|
for (let col = 0; col < 8; col++) {
|
||||||
let fingerprint = '';
|
for (let row = 0; row < 8; row++) {
|
||||||
for (let col = 0; col < 8; col++) {
|
const left = data[(row * 8) + col];
|
||||||
for (let row = 0; row < 8; row++) {
|
const right = data[(row * 8) + col + 1];
|
||||||
const left = data[(row * 8) + col];
|
fingerprint = fingerprint + (left < right ? '1' : '0');
|
||||||
const right = data[(row * 8) + col + 1];
|
|
||||||
fingerprint = fingerprint + (left < right ? '1' : '0');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
callback(null, fingerprint);
|
|
||||||
}
|
}
|
||||||
|
return fingerprint;
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
@@ -83,6 +80,8 @@ module.exports = {
|
|||||||
inputPngWithGreyAlpha: getPath('grey-8bit-alpha.png'),
|
inputPngWithGreyAlpha: getPath('grey-8bit-alpha.png'),
|
||||||
inputPngWithOneColor: getPath('2x2_fdcce6.png'),
|
inputPngWithOneColor: getPath('2x2_fdcce6.png'),
|
||||||
inputPngWithTransparency16bit: getPath('tbgn2c16.png'), // http://www.schaik.com/pngsuite/tbgn2c16.png
|
inputPngWithTransparency16bit: getPath('tbgn2c16.png'), // http://www.schaik.com/pngsuite/tbgn2c16.png
|
||||||
|
inputPng8BitGreyBackground: getPath('bgbn4a08.png'), // http://www.schaik.com/pngsuite/bgbn4a08.png
|
||||||
|
inputPng16BitGreyBackground: getPath('bggn4a16.png'), // http://www.schaik.com/pngsuite/bggn4a16.png
|
||||||
inputPng16BitGreyAlpha: getPath('16-bit-grey-alpha.png'), // CC-BY-NC-SA florc http://www.colourlovers.com/pattern/50713/pat
|
inputPng16BitGreyAlpha: getPath('16-bit-grey-alpha.png'), // CC-BY-NC-SA florc http://www.colourlovers.com/pattern/50713/pat
|
||||||
inputPngOverlayLayer0: getPath('alpha-layer-0-background.png'),
|
inputPngOverlayLayer0: getPath('alpha-layer-0-background.png'),
|
||||||
inputPngOverlayLayer1: getPath('alpha-layer-1-fill.png'),
|
inputPngOverlayLayer1: getPath('alpha-layer-1-fill.png'),
|
||||||
@@ -102,6 +101,7 @@ module.exports = {
|
|||||||
inputPngTrimSpecificColour16bit: getPath('Flag_of_the_Netherlands-16bit.png'), // convert Flag_of_the_Netherlands.png -depth 16 Flag_of_the_Netherlands-16bit.png
|
inputPngTrimSpecificColour16bit: getPath('Flag_of_the_Netherlands-16bit.png'), // convert Flag_of_the_Netherlands.png -depth 16 Flag_of_the_Netherlands-16bit.png
|
||||||
inputPngTrimSpecificColourIncludeAlpha: getPath('Flag_of_the_Netherlands-alpha.png'), // convert Flag_of_the_Netherlands.png -alpha set -background none -channel A -evaluate multiply 0.5 +channel Flag_of_the_Netherlands-alpha.png
|
inputPngTrimSpecificColourIncludeAlpha: getPath('Flag_of_the_Netherlands-alpha.png'), // convert Flag_of_the_Netherlands.png -alpha set -background none -channel A -evaluate multiply 0.5 +channel Flag_of_the_Netherlands-alpha.png
|
||||||
inputPngUint32Limit: getPath('65536-uint32-limit.png'), // https://alexandre.alapetite.fr/doc-alex/large-image/
|
inputPngUint32Limit: getPath('65536-uint32-limit.png'), // https://alexandre.alapetite.fr/doc-alex/large-image/
|
||||||
|
inputPngWithProPhotoProfile: getPath('prophoto.png'),
|
||||||
|
|
||||||
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
||||||
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
||||||
@@ -139,6 +139,7 @@ module.exports = {
|
|||||||
|
|
||||||
testPattern: getPath('test-pattern.png'),
|
testPattern: getPath('test-pattern.png'),
|
||||||
|
|
||||||
|
inputPngWithTransparent: getPath('d.png'),
|
||||||
// Path for tests requiring human inspection
|
// Path for tests requiring human inspection
|
||||||
path: getPath,
|
path: getPath,
|
||||||
|
|
||||||
@@ -150,46 +151,44 @@ module.exports = {
|
|||||||
// Verify similarity of expected vs actual images via fingerprint
|
// Verify similarity of expected vs actual images via fingerprint
|
||||||
// Specify distance threshold using `options={threshold: 42}`, default
|
// Specify distance threshold using `options={threshold: 42}`, default
|
||||||
// `threshold` is 5;
|
// `threshold` is 5;
|
||||||
assertSimilar: function (expectedImage, actualImage, options, callback) {
|
assertSimilar: async function (expectedImage, actualImage, options, callback) {
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
callback = options;
|
callback = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
if (typeof options === 'undefined' || options === null) {
|
||||||
if (typeof options === 'undefined' && options === null) {
|
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.threshold === null || typeof options.threshold === 'undefined') {
|
if (options.threshold === null || typeof options.threshold === 'undefined') {
|
||||||
options.threshold = 5; // ~7% threshold
|
options.threshold = 5; // ~7% threshold
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof options.threshold !== 'number') {
|
if (typeof options.threshold !== 'number') {
|
||||||
throw new TypeError('`options.threshold` must be a number');
|
throw new TypeError('`options.threshold` must be a number');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof callback !== 'function') {
|
try {
|
||||||
throw new TypeError('`callback` must be a function');
|
const [expectedFingerprint, actualFingerprint] = await Promise.all([
|
||||||
|
fingerprint(expectedImage),
|
||||||
|
fingerprint(actualImage)
|
||||||
|
]);
|
||||||
|
let distance = 0;
|
||||||
|
for (let i = 0; i < 64; i++) {
|
||||||
|
if (expectedFingerprint[i] !== actualFingerprint[i]) {
|
||||||
|
distance++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (distance > options.threshold) {
|
||||||
|
throw new Error(`Expected maximum similarity distance: ${options.threshold}. Actual: ${distance}.`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (callback) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
fingerprint(expectedImage, function (err, expectedFingerprint) {
|
|
||||||
if (err) return callback(err);
|
|
||||||
fingerprint(actualImage, function (err, actualFingerprint) {
|
|
||||||
if (err) return callback(err);
|
|
||||||
let distance = 0;
|
|
||||||
for (let i = 0; i < 64; i++) {
|
|
||||||
if (expectedFingerprint[i] !== actualFingerprint[i]) {
|
|
||||||
distance++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance > options.threshold) {
|
|
||||||
return callback(new Error('Expected maximum similarity distance: ' + options.threshold + '. Actual: ' + distance + '.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
assertMaxColourDistance: function (actualImagePath, expectedImagePath, acceptedDistance) {
|
assertMaxColourDistance: function (actualImagePath, expectedImagePath, acceptedDistance) {
|
||||||
|
|||||||
BIN
test/fixtures/prophoto.png
vendored
Normal file
|
After Width: | Height: | Size: 556 B |
@@ -59,6 +59,12 @@ sharp('input.jpg')
|
|||||||
|
|
||||||
sharp('input.jpg').resize({ width: 300 }).blur(false).blur(true).toFile('output.jpg');
|
sharp('input.jpg').resize({ width: 300 }).blur(false).blur(true).toFile('output.jpg');
|
||||||
|
|
||||||
|
sharp().blur();
|
||||||
|
sharp().blur(1);
|
||||||
|
sharp().blur({ sigma: 1 });
|
||||||
|
sharp().blur({ sigma: 1, precision: 'approximate' });
|
||||||
|
sharp().blur({ sigma: 1, minAmplitude: 0.8 });
|
||||||
|
|
||||||
sharp({
|
sharp({
|
||||||
create: {
|
create: {
|
||||||
width: 300,
|
width: 300,
|
||||||
@@ -295,6 +301,13 @@ sharp('input.gif')
|
|||||||
[0.2392, 0.4696, 0.0912],
|
[0.2392, 0.4696, 0.0912],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
.recomb([
|
||||||
|
[1,0,0,0],
|
||||||
|
[0,1,0,0],
|
||||||
|
[0,0,1,0],
|
||||||
|
[0,0,0,1],
|
||||||
|
])
|
||||||
|
|
||||||
.modulate({ brightness: 2 })
|
.modulate({ brightness: 2 })
|
||||||
.modulate({ hue: 180 })
|
.modulate({ hue: 180 })
|
||||||
.modulate({ lightness: 10 })
|
.modulate({ lightness: 10 })
|
||||||
@@ -700,4 +713,9 @@ sharp(input).composite([
|
|||||||
density: 72,
|
density: 72,
|
||||||
failOn: "truncated"
|
failOn: "truncated"
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const colour: sharp.Colour = '#fff';
|
||||||
|
const color: sharp.Color = '#fff';
|
||||||
|
sharp({ pdfBackground: colour });
|
||||||
|
sharp({ pdfBackground: color });
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ describe('AVIF', () => {
|
|||||||
// Math.round(13.40625) = 13
|
// Math.round(13.40625) = 13
|
||||||
height: 13,
|
height: 13,
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
space: 'srgb',
|
space: 'srgb',
|
||||||
width: 32
|
width: 32
|
||||||
});
|
});
|
||||||
@@ -55,6 +56,8 @@ describe('AVIF', () => {
|
|||||||
hasProfile: false,
|
hasProfile: false,
|
||||||
height: 26,
|
height: 26,
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
|
bitsPerSample: 8,
|
||||||
pagePrimary: 0,
|
pagePrimary: 0,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
space: 'srgb',
|
space: 'srgb',
|
||||||
@@ -77,6 +80,8 @@ describe('AVIF', () => {
|
|||||||
hasProfile: false,
|
hasProfile: false,
|
||||||
height: 13,
|
height: 13,
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
|
bitsPerSample: 8,
|
||||||
pagePrimary: 0,
|
pagePrimary: 0,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
space: 'srgb',
|
space: 'srgb',
|
||||||
@@ -100,6 +105,8 @@ describe('AVIF', () => {
|
|||||||
hasProfile: false,
|
hasProfile: false,
|
||||||
height: 300,
|
height: 300,
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
|
bitsPerSample: 8,
|
||||||
pagePrimary: 0,
|
pagePrimary: 0,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
space: 'srgb',
|
space: 'srgb',
|
||||||
@@ -124,6 +131,8 @@ describe('AVIF', () => {
|
|||||||
hasProfile: false,
|
hasProfile: false,
|
||||||
height: 26,
|
height: 26,
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
|
bitsPerSample: 8,
|
||||||
pagePrimary: 0,
|
pagePrimary: 0,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
space: 'srgb',
|
space: 'srgb',
|
||||||
|
|||||||
@@ -35,6 +35,19 @@ describe('Blur', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('specific options.sigma 10', function (done) {
|
||||||
|
sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.blur({ sigma: 10 })
|
||||||
|
.toBuffer(function (err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('blur-10.jpg'), data, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('specific radius 0.3', function (done) {
|
it('specific radius 0.3', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
@@ -91,4 +104,54 @@ describe('Blur', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('invalid precision', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputJpg).blur({ sigma: 1, precision: 'invalid' });
|
||||||
|
}, /Expected one of: integer, float, approximate for precision but received invalid of type string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('invalid minAmplitude', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputJpg).blur({ sigma: 1, minAmplitude: 0 });
|
||||||
|
}, /Expected number between 0.001 and 1 for minAmplitude but received 0 of type number/);
|
||||||
|
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputJpg).blur({ sigma: 1, minAmplitude: 1.01 });
|
||||||
|
}, /Expected number between 0.001 and 1 for minAmplitude but received 1.01 of type number/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('specific radius 10 and precision approximate', async () => {
|
||||||
|
const approximate = await sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.blur({ sigma: 10, precision: 'approximate' })
|
||||||
|
.toBuffer();
|
||||||
|
const integer = await sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.blur(10)
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
assert.notDeepEqual(approximate, integer);
|
||||||
|
await fixtures.assertSimilar(fixtures.expected('blur-10.jpg'), approximate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('specific radius 10 and minAmplitude 0.01', async () => {
|
||||||
|
const minAmplitudeLow = await sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.blur({ sigma: 10, minAmplitude: 0.01 })
|
||||||
|
.toBuffer();
|
||||||
|
const minAmplitudeDefault = await sharp(fixtures.inputJpg)
|
||||||
|
.resize(320, 240)
|
||||||
|
.blur(10)
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
assert.notDeepEqual(minAmplitudeLow, minAmplitudeDefault);
|
||||||
|
await fixtures.assertSimilar(fixtures.expected('blur-10.jpg'), minAmplitudeLow);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('options.sigma is required if options object is passed', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp(fixtures.inputJpg).blur({ precision: 'invalid' });
|
||||||
|
}, /Expected number between 0.3 and 1000 for options.sigma but received undefined of type undefined/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ describe('failOn', () => {
|
|||||||
|
|
||||||
it('returns errors to callback for truncated JPEG', function (done) {
|
it('returns errors to callback for truncated JPEG', function (done) {
|
||||||
sharp(fixtures.inputJpgTruncated, { failOn: 'truncated' }).toBuffer(function (err, data, info) {
|
sharp(fixtures.inputJpgTruncated, { failOn: 'truncated' }).toBuffer(function (err, data, info) {
|
||||||
assert.ok(err.message.includes('VipsJpeg: Premature end of'), err);
|
assert.ok(err.message.includes('VipsJpeg: premature end of'), err);
|
||||||
assert.strictEqual(data, undefined);
|
assert.strictEqual(data, undefined);
|
||||||
assert.strictEqual(info, undefined);
|
assert.strictEqual(info, undefined);
|
||||||
done();
|
done();
|
||||||
@@ -95,7 +95,7 @@ describe('failOn', () => {
|
|||||||
throw new Error('Expected rejection');
|
throw new Error('Expected rejection');
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
done(err.message.includes('VipsJpeg: Premature end of') ? undefined : err);
|
done(err.message.includes('VipsJpeg: premature end of') ? undefined : err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ describe('GIF input', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
it('Animated GIF first page to PNG', () =>
|
it('Animated GIF first page to non-animated GIF', () =>
|
||||||
sharp(fixtures.inputGifAnimated)
|
sharp(fixtures.inputGifAnimated)
|
||||||
.toBuffer({ resolveWithObject: true })
|
.toBuffer({ resolveWithObject: true })
|
||||||
.then(({ data, info }) => {
|
.then(({ data, info }) => {
|
||||||
@@ -49,10 +49,12 @@ describe('GIF input', () => {
|
|||||||
assert.strictEqual(80, info.width);
|
assert.strictEqual(80, info.width);
|
||||||
assert.strictEqual(80, info.height);
|
assert.strictEqual(80, info.height);
|
||||||
assert.strictEqual(4, info.channels);
|
assert.strictEqual(4, info.channels);
|
||||||
|
assert.strictEqual(undefined, info.pages);
|
||||||
|
assert.strictEqual(undefined, info.pageHeight);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
it('Animated GIF all pages to PNG "toilet roll"', () =>
|
it('Animated GIF round trip', () =>
|
||||||
sharp(fixtures.inputGifAnimated, { pages: -1 })
|
sharp(fixtures.inputGifAnimated, { pages: -1 })
|
||||||
.toBuffer({ resolveWithObject: true })
|
.toBuffer({ resolveWithObject: true })
|
||||||
.then(({ data, info }) => {
|
.then(({ data, info }) => {
|
||||||
@@ -62,6 +64,8 @@ describe('GIF input', () => {
|
|||||||
assert.strictEqual(80, info.width);
|
assert.strictEqual(80, info.width);
|
||||||
assert.strictEqual(2400, info.height);
|
assert.strictEqual(2400, info.height);
|
||||||
assert.strictEqual(4, info.channels);
|
assert.strictEqual(4, info.channels);
|
||||||
|
assert.strictEqual(30, info.pages);
|
||||||
|
assert.strictEqual(80, info.pageHeight);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -893,6 +893,27 @@ describe('Input/output', function () {
|
|||||||
sharp({ subifd: 1.2 });
|
sharp({ subifd: 1.2 });
|
||||||
}, /Expected integer between -1 and 100000 for subifd but received 1.2 of type number/);
|
}, /Expected integer between -1 and 100000 for subifd but received 1.2 of type number/);
|
||||||
});
|
});
|
||||||
|
it('Valid pdfBackground property (string)', function () {
|
||||||
|
sharp({ pdfBackground: '#00ff00' });
|
||||||
|
});
|
||||||
|
it('Valid pdfBackground property (object)', function () {
|
||||||
|
sharp({ pdfBackground: { r: 0, g: 255, b: 0 } });
|
||||||
|
});
|
||||||
|
it('Invalid pdfBackground property (string) throws', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ pdfBackground: '00ff00' });
|
||||||
|
}, /Unable to parse color from string/);
|
||||||
|
});
|
||||||
|
it('Invalid pdfBackground property (number) throws', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ pdfBackground: 255 });
|
||||||
|
}, /Expected object or string for background/);
|
||||||
|
});
|
||||||
|
it('Invalid pdfBackground property (object)', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
sharp({ pdfBackground: { red: 0, green: 255, blue: 0 } });
|
||||||
|
}, /Unable to parse color from object/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Fails when writing to missing directory', async () => {
|
it('Fails when writing to missing directory', async () => {
|
||||||
|
|||||||
@@ -72,6 +72,15 @@ describe('libvips binaries', function () {
|
|||||||
const useGlobalLibvips = libvips.useGlobalLibvips();
|
const useGlobalLibvips = libvips.useGlobalLibvips();
|
||||||
assert.strictEqual(true, useGlobalLibvips);
|
assert.strictEqual(true, useGlobalLibvips);
|
||||||
|
|
||||||
|
let logged = false;
|
||||||
|
const logger = function (message) {
|
||||||
|
assert.strictEqual(message, 'Detected SHARP_FORCE_GLOBAL_LIBVIPS, skipping search for globally-installed libvips');
|
||||||
|
logged = true;
|
||||||
|
};
|
||||||
|
const useGlobalLibvipsWithLogger = libvips.useGlobalLibvips(logger);
|
||||||
|
assert.strictEqual(true, useGlobalLibvipsWithLogger);
|
||||||
|
assert.strictEqual(true, logged);
|
||||||
|
|
||||||
delete process.env.SHARP_FORCE_GLOBAL_LIBVIPS;
|
delete process.env.SHARP_FORCE_GLOBAL_LIBVIPS;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -129,7 +138,7 @@ describe('libvips binaries', function () {
|
|||||||
});
|
});
|
||||||
it('arch', () => {
|
it('arch', () => {
|
||||||
const [, arch] = libvips.runtimePlatformArch().split('-');
|
const [, arch] = libvips.runtimePlatformArch().split('-');
|
||||||
assert.strict(['arm', 'arm64', 'ia32', 'x64'].includes(arch));
|
assert.strict(['arm', 'arm64', 'ia32', 'x64', 'ppc64'].includes(arch));
|
||||||
});
|
});
|
||||||
it('isUnsupportedNodeRuntime', () => {
|
it('isUnsupportedNodeRuntime', () => {
|
||||||
assert.strictEqual(libvips.isUnsupportedNodeRuntime(), undefined);
|
assert.strictEqual(libvips.isUnsupportedNodeRuntime(), undefined);
|
||||||
@@ -170,7 +179,7 @@ describe('libvips binaries', function () {
|
|||||||
process.env.npm_config_arch = 's390x';
|
process.env.npm_config_arch = 's390x';
|
||||||
process.env.npm_config_libc = '';
|
process.env.npm_config_libc = '';
|
||||||
const locatorHash = libvips.yarnLocator();
|
const locatorHash = libvips.yarnLocator();
|
||||||
assert.strictEqual(locatorHash, '45978c229d');
|
assert.strictEqual(locatorHash, '9b2ea457de');
|
||||||
delete process.env.npm_config_platform;
|
delete process.env.npm_config_platform;
|
||||||
delete process.env.npm_config_arch;
|
delete process.env.npm_config_arch;
|
||||||
delete process.env.npm_config_libc;
|
delete process.env.npm_config_libc;
|
||||||
|
|||||||
@@ -154,6 +154,31 @@ describe('Image metadata', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('PNG with comment', function (done) {
|
||||||
|
sharp(fixtures.inputPngTestJoinChannel).metadata(function (err, metadata) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', metadata.format);
|
||||||
|
assert.strictEqual('undefined', typeof metadata.size);
|
||||||
|
assert.strictEqual(320, metadata.width);
|
||||||
|
assert.strictEqual(240, metadata.height);
|
||||||
|
assert.strictEqual('b-w', metadata.space);
|
||||||
|
assert.strictEqual(1, metadata.channels);
|
||||||
|
assert.strictEqual('uchar', metadata.depth);
|
||||||
|
assert.strictEqual(72, metadata.density);
|
||||||
|
assert.strictEqual('undefined', typeof metadata.chromaSubsampling);
|
||||||
|
assert.strictEqual(false, metadata.isProgressive);
|
||||||
|
assert.strictEqual(false, metadata.hasProfile);
|
||||||
|
assert.strictEqual(false, metadata.hasAlpha);
|
||||||
|
assert.strictEqual('undefined', typeof metadata.orientation);
|
||||||
|
assert.strictEqual('undefined', typeof metadata.exif);
|
||||||
|
assert.strictEqual('undefined', typeof metadata.icc);
|
||||||
|
assert.strictEqual(1, metadata.comments.length);
|
||||||
|
assert.strictEqual('Comment', metadata.comments[0].keyword);
|
||||||
|
assert.strictEqual('Created with GIMP', metadata.comments[0].text);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Transparent PNG', function (done) {
|
it('Transparent PNG', function (done) {
|
||||||
sharp(fixtures.inputPngWithTransparency).metadata(function (err, metadata) {
|
sharp(fixtures.inputPngWithTransparency).metadata(function (err, metadata) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -176,6 +201,48 @@ describe('Image metadata', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('PNG with greyscale bKGD chunk - 8 bit', async () => {
|
||||||
|
const data = await sharp(fixtures.inputPng8BitGreyBackground).metadata();
|
||||||
|
assert.deepStrictEqual(data, {
|
||||||
|
background: {
|
||||||
|
gray: 0
|
||||||
|
},
|
||||||
|
bitsPerSample: 8,
|
||||||
|
channels: 2,
|
||||||
|
density: 72,
|
||||||
|
depth: 'uchar',
|
||||||
|
format: 'png',
|
||||||
|
hasAlpha: true,
|
||||||
|
hasProfile: false,
|
||||||
|
height: 32,
|
||||||
|
isPalette: false,
|
||||||
|
isProgressive: false,
|
||||||
|
space: 'b-w',
|
||||||
|
width: 32
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('PNG with greyscale bKGD chunk - 16 bit', async () => {
|
||||||
|
const data = await sharp(fixtures.inputPng16BitGreyBackground).metadata();
|
||||||
|
assert.deepStrictEqual(data, {
|
||||||
|
background: {
|
||||||
|
gray: 67
|
||||||
|
},
|
||||||
|
bitsPerSample: 16,
|
||||||
|
channels: 2,
|
||||||
|
density: 72,
|
||||||
|
depth: 'ushort',
|
||||||
|
format: 'png',
|
||||||
|
hasAlpha: true,
|
||||||
|
hasProfile: false,
|
||||||
|
height: 32,
|
||||||
|
isPalette: false,
|
||||||
|
isProgressive: false,
|
||||||
|
space: 'grey16',
|
||||||
|
width: 32
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('WebP', function (done) {
|
it('WebP', function (done) {
|
||||||
sharp(fixtures.inputWebP).metadata(function (err, metadata) {
|
sharp(fixtures.inputWebP).metadata(function (err, metadata) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -576,6 +643,17 @@ describe('Image metadata', function () {
|
|||||||
assert.strictEqual(description, 'Generic RGB Profile');
|
assert.strictEqual(description, 'Generic RGB Profile');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keep existing ICC profile, avoid colour transform', async () => {
|
||||||
|
const [r, g, b] = await sharp(fixtures.inputPngWithProPhotoProfile)
|
||||||
|
.keepIccProfile()
|
||||||
|
.raw()
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
assert.strictEqual(r, 131);
|
||||||
|
assert.strictEqual(g, 141);
|
||||||
|
assert.strictEqual(b, 192);
|
||||||
|
});
|
||||||
|
|
||||||
it('keep existing CMYK ICC profile', async () => {
|
it('keep existing CMYK ICC profile', async () => {
|
||||||
const data = await sharp(fixtures.inputJpgWithCmykProfile)
|
const data = await sharp(fixtures.inputJpgWithCmykProfile)
|
||||||
.pipelineColourspace('cmyk')
|
.pipelineColourspace('cmyk')
|
||||||
@@ -616,13 +694,13 @@ describe('Image metadata', function () {
|
|||||||
.png()
|
.png()
|
||||||
.withIccProfile(fixtures.path('invalid-illuminant.icc'));
|
.withIccProfile(fixtures.path('invalid-illuminant.icc'));
|
||||||
|
|
||||||
let warningEmitted = '';
|
const warningsEmitted = [];
|
||||||
img.on('warning', (warning) => {
|
img.on('warning', (warning) => {
|
||||||
warningEmitted = warning;
|
warningsEmitted.push(warning);
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await img.toBuffer();
|
const data = await img.toBuffer();
|
||||||
assert.strictEqual('Invalid profile', warningEmitted);
|
assert.strict(warningsEmitted.includes('Invalid profile'));
|
||||||
|
|
||||||
const metadata = await sharp(data).metadata();
|
const metadata = await sharp(data).metadata();
|
||||||
assert.strictEqual(3, metadata.channels);
|
assert.strictEqual(3, metadata.channels);
|
||||||
@@ -842,6 +920,8 @@ describe('Image metadata', function () {
|
|||||||
channels: 3,
|
channels: 3,
|
||||||
depth: 'uchar',
|
depth: 'uchar',
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: false,
|
||||||
|
bitsPerSample: 8,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
pagePrimary: 0,
|
pagePrimary: 0,
|
||||||
compression: 'av1',
|
compression: 'av1',
|
||||||
@@ -895,7 +975,7 @@ describe('Image metadata', function () {
|
|||||||
sharp(fixtures.inputJpgWithCorruptHeader)
|
sharp(fixtures.inputJpgWithCorruptHeader)
|
||||||
.metadata(function (err) {
|
.metadata(function (err) {
|
||||||
assert.strictEqual(true, !!err);
|
assert.strictEqual(true, !!err);
|
||||||
assert.ok(err.message.includes('Input file has corrupt header: VipsJpeg: Premature end of'), err);
|
assert.ok(err.message.includes('Input file has corrupt header: VipsJpeg: premature end of'), err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -904,7 +984,7 @@ describe('Image metadata', function () {
|
|||||||
sharp(fs.readFileSync(fixtures.inputJpgWithCorruptHeader))
|
sharp(fs.readFileSync(fixtures.inputJpgWithCorruptHeader))
|
||||||
.metadata(function (err) {
|
.metadata(function (err) {
|
||||||
assert.strictEqual(true, !!err);
|
assert.strictEqual(true, !!err);
|
||||||
assert.ok(err.message.includes('Input buffer has corrupt header: VipsJpeg: Premature end of'), err);
|
assert.ok(err.message.includes('Input buffer has corrupt header: VipsJpeg: premature end of'), err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ const assertNormalized = function (data) {
|
|||||||
min = Math.min(min, data[i]);
|
min = Math.min(min, data[i]);
|
||||||
max = Math.max(max, data[i]);
|
max = Math.max(max, data[i]);
|
||||||
}
|
}
|
||||||
assert.strictEqual(0, min);
|
assert.strictEqual(0, min, 'min too high');
|
||||||
assert.ok([254, 255].includes(max));
|
assert.ok(max > 248, 'max too low');
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Normalization', function () {
|
describe('Normalization', function () {
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ describe('PNG', function () {
|
|||||||
density: 72,
|
density: 72,
|
||||||
depth: 'uchar',
|
depth: 'uchar',
|
||||||
isProgressive: false,
|
isProgressive: false,
|
||||||
|
isPalette: true,
|
||||||
|
bitsPerSample: 8,
|
||||||
paletteBitDepth: 8,
|
paletteBitDepth: 8,
|
||||||
hasProfile: false,
|
hasProfile: false,
|
||||||
hasAlpha: false
|
hasAlpha: false
|
||||||
@@ -218,8 +220,10 @@ describe('PNG', function () {
|
|||||||
.png({ colours: 2, palette: false })
|
.png({ colours: 2, palette: false })
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
const { channels, paletteBitDepth, size, space } = await sharp(data).metadata();
|
const { channels, isPalette, bitsPerSample, paletteBitDepth, size, space } = await sharp(data).metadata();
|
||||||
assert.strictEqual(channels, 1);
|
assert.strictEqual(channels, 1);
|
||||||
|
assert.strictEqual(isPalette, false);
|
||||||
|
assert.strictEqual(bitsPerSample, 1);
|
||||||
assert.strictEqual(paletteBitDepth, undefined);
|
assert.strictEqual(paletteBitDepth, undefined);
|
||||||
assert.strictEqual(size, 89);
|
assert.strictEqual(size, 89);
|
||||||
assert.strictEqual(space, 'b-w');
|
assert.strictEqual(space, 'b-w');
|
||||||
|
|||||||
@@ -121,6 +121,29 @@ describe('Recomb', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('applies opacity 30% to the image', function (done) {
|
||||||
|
const output = fixtures.path('output.recomb-opacity.png');
|
||||||
|
sharp(fixtures.inputPngWithTransparent)
|
||||||
|
.recomb([
|
||||||
|
[1, 0, 0, 0],
|
||||||
|
[0, 1, 0, 0],
|
||||||
|
[0, 0, 1, 0],
|
||||||
|
[0, 0, 0, 0.3]
|
||||||
|
])
|
||||||
|
.toFile(output, function (err, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('png', info.format);
|
||||||
|
assert.strictEqual(48, info.width);
|
||||||
|
assert.strictEqual(48, info.height);
|
||||||
|
fixtures.assertMaxColourDistance(
|
||||||
|
output,
|
||||||
|
fixtures.expected('d-opacity-30.png'),
|
||||||
|
17
|
||||||
|
);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('invalid matrix specification', function () {
|
describe('invalid matrix specification', function () {
|
||||||
it('missing', function () {
|
it('missing', function () {
|
||||||
assert.throws(function () {
|
assert.throws(function () {
|
||||||
|
|||||||
@@ -417,6 +417,7 @@ describe('Rotation', function () {
|
|||||||
it('Flip and flop', function (done) {
|
it('Flip and flop', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320)
|
.resize(320)
|
||||||
|
.flip()
|
||||||
.flop()
|
.flop()
|
||||||
.toBuffer(function (err, data, info) {
|
.toBuffer(function (err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ describe('Image Stats', function () {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.332915340666659));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.7883011147075762));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.7883011147075762));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
@@ -272,7 +272,7 @@ describe('Image Stats', function () {
|
|||||||
|
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.51758075132966));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.51758075132966));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 9.959951636662941));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 9.971384105278734));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
assert.strictEqual(40, r);
|
assert.strictEqual(40, r);
|
||||||
@@ -336,8 +336,8 @@ describe('Image Stats', function () {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 6.087309412541799));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 6.08118048729375));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 2.9250574456255682));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 2.936767879098001));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
assert.strictEqual(120, r);
|
assert.strictEqual(120, r);
|
||||||
@@ -484,7 +484,7 @@ describe('Image Stats', function () {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.332915340666659));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
@@ -552,7 +552,7 @@ describe('Image Stats', function () {
|
|||||||
|
|
||||||
return pipeline.stats().then(function (stats) {
|
return pipeline.stats().then(function (stats) {
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.332915340666659));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
@@ -615,7 +615,7 @@ describe('Image Stats', function () {
|
|||||||
it('File in, Promise out', function () {
|
it('File in, Promise out', function () {
|
||||||
return sharp(fixtures.inputJpg).stats().then(function (stats) {
|
return sharp(fixtures.inputJpg).stats().then(function (stats) {
|
||||||
assert.strictEqual(true, stats.isOpaque);
|
assert.strictEqual(true, stats.isOpaque);
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.319914765248541));
|
assert.strictEqual(true, isInAcceptableRange(stats.entropy, 7.332915340666659));
|
||||||
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
assert.strictEqual(true, isInAcceptableRange(stats.sharpness, 0.788301114707569));
|
||||||
|
|
||||||
const { r, g, b } = stats.dominant;
|
const { r, g, b } = stats.dominant;
|
||||||
@@ -682,8 +682,8 @@ describe('Image Stats', function () {
|
|||||||
return Promise
|
return Promise
|
||||||
.all([original, blurred])
|
.all([original, blurred])
|
||||||
.then(([original, blurred]) => {
|
.then(([original, blurred]) => {
|
||||||
assert.strictEqual(true, isInAcceptableRange(original.sharpness, 0.7883011147075476));
|
assert.strictEqual(true, isInAcceptableRange(original.sharpness, 0.789046400439488));
|
||||||
assert.strictEqual(true, isInAcceptableRange(blurred.sharpness, 0.4791559805997398));
|
assert.strictEqual(true, isInAcceptableRange(blurred.sharpness, 0.47985138441709047));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
const eachLimit = require('async/eachLimit');
|
|
||||||
const extractZip = require('extract-zip');
|
const extractZip = require('extract-zip');
|
||||||
|
|
||||||
const sharp = require('../../');
|
const sharp = require('../../');
|
||||||
@@ -31,11 +30,10 @@ const assertDeepZoomTiles = function (directory, expectedSize, expectedLevels, d
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Verify each tile is <= expectedSize
|
// Verify each tile is <= expectedSize
|
||||||
eachLimit(tiles, 8, function (tile, done) {
|
Promise.all(tiles.map(function (tile) {
|
||||||
sharp(tile).metadata(function (err, metadata) {
|
return sharp(tile)
|
||||||
if (err) {
|
.metadata()
|
||||||
done(err);
|
.then(function (metadata) {
|
||||||
} else {
|
|
||||||
assert.strictEqual('jpeg', metadata.format);
|
assert.strictEqual('jpeg', metadata.format);
|
||||||
assert.strictEqual('srgb', metadata.space);
|
assert.strictEqual('srgb', metadata.space);
|
||||||
assert.strictEqual(3, metadata.channels);
|
assert.strictEqual(3, metadata.channels);
|
||||||
@@ -43,10 +41,10 @@ const assertDeepZoomTiles = function (directory, expectedSize, expectedLevels, d
|
|||||||
assert.strictEqual(false, metadata.hasAlpha);
|
assert.strictEqual(false, metadata.hasAlpha);
|
||||||
assert.strictEqual(true, metadata.width <= expectedSize);
|
assert.strictEqual(true, metadata.width <= expectedSize);
|
||||||
assert.strictEqual(true, metadata.height <= expectedSize);
|
assert.strictEqual(true, metadata.height <= expectedSize);
|
||||||
done();
|
});
|
||||||
}
|
}))
|
||||||
});
|
.then(() => done())
|
||||||
}, done);
|
.catch(done);
|
||||||
};
|
};
|
||||||
|
|
||||||
const assertZoomifyTiles = function (directory, expectedTileSize, expectedLevels, done) {
|
const assertZoomifyTiles = function (directory, expectedTileSize, expectedLevels, done) {
|
||||||
@@ -485,7 +483,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
fs.stat(path.join(directory, 'ImageProperties.xml'), function (err, stat) {
|
fs.stat(path.join(directory, 'ImageProperties.xml'), function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
@@ -511,7 +509,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
assertZoomifyTiles(directory, 256, 1, done);
|
assertZoomifyTiles(directory, 256, 1, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -532,7 +530,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
assertZoomifyTiles(directory, 256, 5, done);
|
assertZoomifyTiles(directory, 256, 5, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -553,7 +551,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
assertZoomifyTiles(directory, 256, 13, done);
|
assertZoomifyTiles(directory, 256, 13, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -577,7 +575,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2048, info.width);
|
assert.strictEqual(2048, info.width);
|
||||||
assert.strictEqual(1536, info.height);
|
assert.strictEqual(1536, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
assertZoomifyTiles(directory, 256, 4, done);
|
assertZoomifyTiles(directory, 256, 4, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -596,7 +594,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
fs.stat(path.join(directory, '0', '0', '0.jpg'), function (err, stat) {
|
fs.stat(path.join(directory, '0', '0', '0.jpg'), function (err, stat) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, stat.isFile());
|
assert.strictEqual(true, stat.isFile());
|
||||||
@@ -623,7 +621,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
const sample = path.join(directory, '0', '0', '0.jpg');
|
const sample = path.join(directory, '0', '0', '0.jpg');
|
||||||
sharp(sample).metadata(function (err, metadata) {
|
sharp(sample).metadata(function (err, metadata) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -660,7 +658,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
const sample = path.join(directory, '0', '0', '0.png');
|
const sample = path.join(directory, '0', '0', '0.png');
|
||||||
sharp(sample).metadata(function (err, metadata) {
|
sharp(sample).metadata(function (err, metadata) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -698,7 +696,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
const sample = path.join(directory, '0', '0', '0.webp');
|
const sample = path.join(directory, '0', '0', '0.webp');
|
||||||
sharp(sample).metadata(function (err, metadata) {
|
sharp(sample).metadata(function (err, metadata) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -734,8 +732,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
|
|
||||||
assertGoogleTiles(directory, 256, 1, done);
|
assertGoogleTiles(directory, 256, 1, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -756,8 +753,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
|
|
||||||
assertGoogleTiles(directory, 256, 5, done);
|
assertGoogleTiles(directory, 256, 5, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -781,8 +777,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2809, info.width);
|
assert.strictEqual(2809, info.width);
|
||||||
assert.strictEqual(2074, info.height);
|
assert.strictEqual(2074, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
|
|
||||||
assertGoogleTiles(directory, 256, 5, done);
|
assertGoogleTiles(directory, 256, 5, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -802,7 +797,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
|
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -822,7 +817,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
|
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -844,7 +839,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
const infoJson = require(path.join(directory, 'info.json'));
|
const infoJson = require(path.join(directory, 'info.json'));
|
||||||
assert.strictEqual('http://iiif.io/api/image/2/context.json', infoJson['@context']);
|
assert.strictEqual('http://iiif.io/api/image/2/context.json', infoJson['@context']);
|
||||||
assert.strictEqual(`${id}/${name}`, infoJson['@id']);
|
assert.strictEqual(`${id}/${name}`, infoJson['@id']);
|
||||||
@@ -874,7 +869,7 @@ describe('Tile', function () {
|
|||||||
assert.strictEqual(2725, info.width);
|
assert.strictEqual(2725, info.width);
|
||||||
assert.strictEqual(2225, info.height);
|
assert.strictEqual(2225, info.height);
|
||||||
assert.strictEqual(3, info.channels);
|
assert.strictEqual(3, info.channels);
|
||||||
assert.strictEqual('number', typeof info.size);
|
assert.strictEqual(undefined, info.size);
|
||||||
const infoJson = require(path.join(directory, 'info.json'));
|
const infoJson = require(path.join(directory, 'info.json'));
|
||||||
assert.strictEqual('http://iiif.io/api/image/3/context.json', infoJson['@context']);
|
assert.strictEqual('http://iiif.io/api/image/3/context.json', infoJson['@context']);
|
||||||
assert.strictEqual('ImageService3', infoJson.type);
|
assert.strictEqual('ImageService3', infoJson.type);
|
||||||
|
|||||||
@@ -102,6 +102,29 @@ describe('WebP', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can produce a different file size using smartDeblock', () =>
|
||||||
|
sharp(fixtures.inputPngOverlayLayer0)
|
||||||
|
.resize(320, 240)
|
||||||
|
.webp({ quality: 30, smartDeblock: false })
|
||||||
|
.toBuffer()
|
||||||
|
.then(withoutSmartDeblock =>
|
||||||
|
sharp(fixtures.inputPngOverlayLayer0)
|
||||||
|
.resize(320, 240)
|
||||||
|
.webp({ quality: 30, smartDeblock: true })
|
||||||
|
.toBuffer()
|
||||||
|
.then(withSmartDeblock => {
|
||||||
|
assert.strictEqual(true, withSmartDeblock.length !== withoutSmartDeblock.length);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
it('invalid smartDeblock throws', () => {
|
||||||
|
assert.throws(
|
||||||
|
() => sharp().webp({ smartDeblock: 1 }),
|
||||||
|
/Expected boolean for webpSmartDeblock but received 1 of type number/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should produce a different file size with specific preset', () =>
|
it('should produce a different file size with specific preset', () =>
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
|
|||||||