Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: lovell/sharp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.26.2
Choose a base ref
...
head repository: lovell/sharp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.33.3
Choose a head ref

Commits on Oct 23, 2020

  1. CI: add Node.js 15 (#2415)

    nstepien authored Oct 23, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e6a035e View commit details

Commits on Nov 16, 2020

  1. Docs: use of N-API removes Electron-specific binaries

    Clarify Lambda deployment for Windows/macOS users
    lovell committed Nov 16, 2020
    Copy the full SHA
    ab653ca View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2872602 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0f473fe View commit details
  4. Docs: changelog for #2336

    lovell committed Nov 16, 2020
    Copy the full SHA
    4671810 View commit details
  5. Bump dev dependencies

    lovell committed Nov 16, 2020
    Copy the full SHA
    2678d7a View commit details
  6. Copy the full SHA
    53dd313 View commit details
  7. Copy the full SHA
    fabe720 View commit details
  8. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    65acd96 View commit details
  9. Docs: changelog entry for #2412

    lovell committed Nov 16, 2020
    Copy the full SHA
    93455f8 View commit details
  10. Release v0.26.3

    lovell committed Nov 16, 2020
    Copy the full SHA
    c10888e View commit details

Commits on Dec 9, 2020

  1. Copy the full SHA
    a0d89ed View commit details

Commits on Dec 18, 2020

  1. Upgrade to libvips 8.10.5, AVIF support in prebuilt binaries

    Remove experimental status from HEIF, changing defaults
    to prefer royalty-free AV1 over patent-encumbered HEVC
    lovell committed Dec 18, 2020
    Copy the full SHA
    103ec0d View commit details
  2. Copy the full SHA
    e59e146 View commit details

Commits on Dec 20, 2020

  1. Copy the full SHA
    ee54ce9 View commit details
  2. Copy the full SHA
    ef964b5 View commit details
  3. Copy the full SHA
    7c08a09 View commit details
  4. Copy the full SHA
    182beaa View commit details
  5. Allow for negative top/left offsets in composite overlays

    A top or left offset value of -1 will no longer mean that the
    value is not set, but will now be an actual offset of -1.
    
    INT_MIN for left & top will mean that the values are not set.
    
    Co-authored-by: Christian Flintrup <chr@gigahost.dk>
    2 people authored and lovell committed Dec 20, 2020
    Copy the full SHA
    0267614 View commit details

Commits on Dec 21, 2020

  1. Copy the full SHA
    2bbd9b2 View commit details
  2. Copy the full SHA
    0e62bde View commit details
  3. Copy the full SHA
    774d782 View commit details
  4. Copy the full SHA
    f4e259d View commit details

Commits on Dec 22, 2020

  1. Copy the full SHA
    4debc46 View commit details
  2. Release v0.27.0

    lovell committed Dec 22, 2020
    Copy the full SHA
    b2a0b8c View commit details

Commits on Jan 1, 2021

  1. Copy the full SHA
    39ddb6a View commit details
  2. Copy the full SHA
    bf1b326 View commit details

Commits on Jan 6, 2021

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4821a11 View commit details
  2. Docs: changelog entry for #2511

    lovell committed Jan 6, 2021
    Copy the full SHA
    a7003e9 View commit details
  3. Copy the full SHA
    d6376c3 View commit details
  4. Copy the full SHA
    138e60a View commit details

Commits on Jan 13, 2021

  1. Ensure tests pass with latest libvips master branch

    Expose forthcoming HEIF features where available
    lovell committed Jan 13, 2021
    Copy the full SHA
    8d49b7d View commit details
  2. Bump devDependencies

    lovell committed Jan 13, 2021
    Copy the full SHA
    f7e2b36 View commit details
  3. Copy the full SHA
    bba00c2 View commit details
  4. Copy the full SHA
    79170af View commit details
  5. Copy the full SHA
    290df1b View commit details
  6. Copy the full SHA
    762d591 View commit details

Commits on Jan 15, 2021

  1. Copy the full SHA
    5031c83 View commit details

Commits on Jan 16, 2021

  1. Copy the full SHA
    419cbe5 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c9f85fe View commit details
  3. Copy the full SHA
    1dd93c1 View commit details

Commits on Jan 18, 2021

  1. Copy the full SHA
    4c57ac2 View commit details

Commits on Jan 24, 2021

  1. Copy the full SHA
    f09be93 View commit details
  2. Copy the full SHA
    98349bd View commit details

Commits on Jan 26, 2021

  1. Copy the full SHA
    0bb8cb9 View commit details
  2. Copy the full SHA
    ceff628 View commit details
  3. Avoid calling g_type_from_name #2535

    kleisauke authored and lovell committed Jan 26, 2021
    Copy the full SHA
    573ed5f View commit details
  4. Copy the full SHA
    24d9e53 View commit details
  5. Copy the full SHA
    67213ae View commit details
  6. Copy the full SHA
    171aade View commit details
Showing 313 changed files with 18,578 additions and 10,621 deletions.
105 changes: 105 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
version: 2.1

workflows:
build:
jobs:
- linux-arm64-glibc-node-18:
filters:
tags:
only: /^v.*/
- linux-arm64-musl-node-18:
filters:
tags:
only: /^v.*/
- linux-arm64-glibc-node-20:
filters:
tags:
only: /^v.*/
- linux-arm64-musl-node-20:
filters:
tags:
only: /^v.*/

jobs:
linux-arm64-glibc-node-18:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp arm64v8/debian:bullseye
sudo docker exec sharp sh -c "apt-get update && apt-get install -y build-essential git python3 curl fonts-noto-core"
sudo docker exec sharp sh -c "mkdir -p /etc/apt/keyrings"
sudo docker exec sharp sh -c "curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg"
sudo docker exec sharp sh -c "echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list"
sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linux-arm64=file:./npm/linux-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"cd src && ln -s ../package.json && npx prebuild --upload=$prebuild_upload\" || true"
linux-arm64-glibc-node-20:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --workdir /mnt/sharp arm64v8/debian:bullseye
sudo docker exec sharp sh -c "apt-get update && apt-get install -y build-essential git python3 curl fonts-noto-core"
sudo docker exec sharp sh -c "mkdir -p /etc/apt/keyrings"
sudo docker exec sharp sh -c "curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg"
sudo docker exec sharp sh -c "echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list"
sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
sudo docker exec sharp sh -c "mkdir -p /mnt/sharp"
sudo docker cp . sharp:/mnt/sharp/.
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linux-arm64=file:./npm/linux-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
linux-arm64-musl-node-18:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:18-alpine3.17
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"cd src && ln -s ../package.json && npx prebuild --upload=$prebuild_upload\" || true"
linux-arm64-musl-node-20:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --workdir /mnt/sharp node:20-alpine3.18
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
sudo docker exec sharp sh -c "mkdir -p /mnt/sharp"
sudo docker cp . sharp:/mnt/sharp/.
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
12 changes: 7 additions & 5 deletions .cirrus.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
freebsd_instance:
image_family: freebsd-13-0-snap
image_family: freebsd-14-0-snap

task:
name: FreeBSD 13.0
name: FreeBSD
env:
IGNORE_OSVERSION: yes
skip_notifications: true
prerequisites_script:
- pkg update -f
- pkg upgrade -y
- pkg install -y pkgconf vips node npm
- pkg install -y devel/git devel/pkgconf graphics/vips www/node20 www/npm
- pkg-config --modversion vips-cpp
install_script:
- npm install --unsafe-perm
- npm install --build-from-source
test_script:
- npm test
- npx mocha --no-config --spec=test/unit/io.js --timeout=30000
1 change: 0 additions & 1 deletion .gitattributes

This file was deleted.

17 changes: 9 additions & 8 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -16,29 +16,30 @@ If a [similar request](https://github.com/lovell/sharp/labels/enhancement) exist
it's probably fastest to add a comment to it about your requirement.

Implementation is usually straightforward if libvips
[already supports](https://libvips.github.io/libvips/API/current/func-list.html)
[already supports](https://www.libvips.org/API/current/func-list.html)
the feature you need.

## Submit a Pull Request to fix a bug

Thank you! To prevent the problem occurring again, please add unit tests that would have failed.

Please select the `master` branch as the destination for your Pull Request so your fix can be included in the next minor release.
Please select the `main` branch as the destination for your Pull Request so your fix can be included in the next minor release.

Please squash your changes into a single commit using a command like `git rebase -i upstream/master`.
Please squash your changes into a single commit using a command like `git rebase -i upstream/main`.

To test C++ changes, you can compile the module using `npm install` and then run the tests using `npm test`.
To test C++ changes, you can compile the module using `npm install --build-from-source` and then run the tests using `npm test`.

## Submit a Pull Request with a new feature

Please add JavaScript [unit tests](https://github.com/lovell/sharp/tree/master/test/unit) to cover your new feature.
Please add JavaScript [unit tests](https://github.com/lovell/sharp/tree/main/test/unit) to cover your new feature.
A test coverage report for the JavaScript code is generated in the `coverage/lcov-report` directory.
Please also update the [TypeScript definitions](https://github.com/lovell/sharp/tree/main/lib/index.d.ts), along with the [type definition tests](https://github.com/lovell/sharp/tree/main/test/types/sharp.test-d.ts).

Where possible, the functional tests use gradient-based perceptual hashes
based on [dHash](http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html)
to compare expected vs actual images.

You deserve to add your details to the [list of contributors](https://github.com/lovell/sharp/blob/master/package.json#L5).
You deserve to add your details to the [list of contributors](https://github.com/lovell/sharp/blob/main/package.json#L5).

Any change that modifies the existing public API should be added to the relevant work-in-progress branch for inclusion in the next major release.

@@ -62,7 +63,7 @@ By way of example, the `background()` method present in v0.20.0 was deprecated i

## Documentation

The public API is documented with [JSDoc](http://usejsdoc.org/) annotated comments.
The public API is documented with [JSDoc](https://jsdoc.app/) annotated comments.

These can be converted to Markdown by running:
```sh
@@ -93,5 +94,5 @@ Please feel free to ask any questions via a
[new issue](https://github.com/lovell/sharp/issues/new).

If you're unable to post details publicly, please
[e-mail](https://github.com/lovell/sharp/blob/master/package.json#L5)
[e-mail](https://github.com/lovell/sharp/blob/main/package.json#L5)
for private, paid consulting.
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Documentation
url: https://sharp.pixelplumbing.com/
about: Installation instructions, complete API documentation with examples, changelog
22 changes: 17 additions & 5 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -5,12 +5,24 @@ labels: enhancement

---

What are you trying to achieve?
## Feature request

Have you searched for similar feature requests?
### What are you trying to achieve?

What would you expect the API to look like?
<!-- Please provide context here. -->

What alternatives have you considered?
### When you searched for similar feature requests, what did you find that might be related?

Is there a sample image that helps explain?
<!-- Please demonstrate your research here. -->

### What would you expect the API to look like?

<!-- Please provide your suggestions here. -->

### What alternatives have you considered?

<!-- Please provide your ideas here. -->

### Please provide sample image(s) that help explain this feature

<!-- Please provide links to one or more images here. -->
63 changes: 56 additions & 7 deletions .github/ISSUE_TEMPLATE/installation.md
Original file line number Diff line number Diff line change
@@ -5,16 +5,65 @@ labels: installation

---

Did you see the [documentation relating to installation](https://sharp.pixelplumbing.com/install)?
<!-- Please try to answer as many of these questions as possible. -->

Have you ensured the architecture and platform of Node.js used for `npm install` is the same as the architecture and platform of Node.js used at runtime?
## Possible install-time or require-time problem

Are you using the latest version? Is the version currently in use as reported by `npm ls sharp` the same as the latest version as reported by `npm view sharp dist-tags.latest`?
<!-- Please place an [x] in the box to confirm. -->

If you are installing as a `root` or `sudo` user, have you tried with the `npm install --unsafe-perm` flag?
- [ ] I have read and understood all of the [documentation relating to installation](https://sharp.pixelplumbing.com/install).
- [ ] I have searched for known bugs relating to this problem in my choice of package manager.

If you are using the `ignore-scripts` feature of `npm`, have you tried with the `npm install --ignore-scripts=false` flag?
You must confirm both of these before continuing.

What is the complete output of running `npm install --verbose sharp`? Have you checked this output for useful error messages?
### Are you using the latest version of sharp?

What is the output of running `npx envinfo --binaries --system`?
<!-- Please place an [x] in the box to confirm. -->

- [ ] I am using the latest version of `sharp` as reported by `npm view sharp dist-tags.latest`.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of `sharp` that is not the latest,
please open an issue against that package instead.

### Are you using a supported runtime?

<!-- Please place an [x] in the relevant box to confirm. -->

- [ ] I am using Node.js with a version that satisfies `^18.17.0 || ^20.3.0 || >=21.0.0`
- [ ] I am using Deno
- [ ] I am using Bun

If you cannot confirm any of these,
please upgrade to the latest version
and try again before opening an issue.

### Are you using a supported package manager and installing optional dependencies?

<!-- Please place an [x] in the relevant box to confirm. -->

- [ ] I am using npm >= 9.6.5 with `--include=optional`
- [ ] I am using yarn >= 3.2.0
- [ ] I am using pnpm >= 7.1.0 with `--no-optional=false`
- [ ] I am using Deno
- [ ] I am using Bun

If you cannot confirm any of these, please upgrade to the latest version of your chosen package manager
and ensure you are allowing the installation of optional or multi-platform dependencies before opening an issue.

### What is the complete error message, including the full stack trace?

<!-- Please provide the error message and stack trace here. -->

### What is the complete output of running `npm install --verbose --foreground-scripts sharp` in an empty directory?

<details>

<!-- Please provide output of `npm install --verbose --foreground-scripts sharp` in an empty directory here. -->

</details>

### What is the output of running `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp`?

<!-- Please provide output of `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp` here. -->
41 changes: 35 additions & 6 deletions .github/ISSUE_TEMPLATE/possible-bug.md
Original file line number Diff line number Diff line change
@@ -7,14 +7,43 @@ labels: triage

<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->

Are you using the latest version? Is the version currently in use as reported by `npm ls sharp` the same as the latest version as reported by `npm view sharp dist-tags.latest`?
## Possible bug

What are the steps to reproduce?
### Is this a possible bug in a feature of sharp, unrelated to installation?

What is the expected behaviour?
<!-- Please place an [x] in the box to confirm. -->

Are you able to provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem?
- [ ] Running `npm install sharp` completes without error.
- [ ] Running `node -e "require('sharp')"` completes without error.

Are you able to provide a sample image that helps explain the problem?
If you cannot confirm both of these, please open an [installation issue](https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md) instead.

What is the output of running `npx envinfo --binaries --system`?
### Are you using the latest version of sharp?

<!-- Please place an [x] in the box to confirm. -->

- [ ] I am using the latest version of `sharp` as reported by `npm view sharp dist-tags.latest`.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of `sharp` that is not the latest, please open an issue against that package instead.

### What is the output of running `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp`?

<!-- Please provide output of the above command here. -->

### What are the steps to reproduce?

<!-- Please enter steps to reproduce here. -->

### What is the expected behaviour?

<!-- Please enter the expected behaviour here. -->

### Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

<!-- Please provide either formatted code or a link to a repo/gist that allows someone else to reproduce here. -->

### Please provide sample image(s) that help explain this problem

<!-- Please provide links to one or more images here. -->
18 changes: 14 additions & 4 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -7,10 +7,20 @@ labels: question

<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->

What are you trying to achieve?
## Question about an existing feature

Have you searched for similar questions?
### What are you trying to achieve?

Are you able to provide a minimal, standalone code sample that demonstrates this question?
<!-- Please provide context here. -->

Are you able to provide a sample image that helps explain the question?
### When you searched for similar issues, what did you find that might be related?

<!-- Please demonstrate your research here. -->

### Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

<!-- Please provide either formatted code or a link to a repo/gist that helps someone else understand here. -->

### Please provide sample image(s) that help explain this question

<!-- Please provide links to one or more images here. -->
18 changes: 18 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Security Policy

## Supported Versions

The latest version of `sharp` as published to npm
and reported by `npm view sharp dist-tags.latest`
is supported with security updates.

## Reporting a Vulnerability

Please use
[e-mail](https://github.com/lovell/sharp/blob/main/package.json#L5)
to report a vulnerability.

You can expect a response within 48 hours
if you are a human reporting a genuine issue.

Thank you in advance.
206 changes: 206 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
name: CI
on:
- push
- pull_request
permissions: {}
jobs:
github-runner:
permissions:
contents: write
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} ${{ matrix.prebuild && '- prebuild' }}
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
container: rockylinux:8
nodejs_arch: x64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: linux-x64
prebuild: true
- os: ubuntu-22.04
container: rockylinux:8
nodejs_arch: x64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: linux-x64
- os: ubuntu-22.04
container: node:18-alpine3.17
nodejs_version_major: 18
platform: linuxmusl-x64
prebuild: true
- os: ubuntu-22.04
container: node:20-alpine3.18
nodejs_version_major: 20
platform: linuxmusl-x64
- os: macos-11
nodejs_arch: x64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: darwin-x64
prebuild: true
- os: macos-11
nodejs_arch: x64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: darwin-x64
- os: macos-14
nodejs_arch: arm64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: darwin-arm64
prebuild: true
- os: macos-14
nodejs_arch: arm64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: darwin-arm64
- os: windows-2019
nodejs_arch: x86
nodejs_version: "18.18.2" # pinned to avoid 18.19.0 and npm 10
nodejs_version_major: 18
platform: win32-ia32
prebuild: true
- os: windows-2019
nodejs_arch: x86
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: win32-ia32
- os: windows-2019
nodejs_arch: x64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: win32-x64
prebuild: true
- os: windows-2019
nodejs_arch: x64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: win32-x64
steps:
- name: Dependencies (Rocky Linux glibc)
if: contains(matrix.container, 'rockylinux')
run: |
dnf install -y gcc-toolset-11-gcc-c++ make git python3 fontconfig google-noto-sans-fonts
echo "/opt/rh/gcc-toolset-11/root/usr/bin" >> $GITHUB_PATH
- name: Dependencies (Linux musl)
if: contains(matrix.container, 'alpine')
run: apk add build-base git python3 font-noto --update-cache
- name: Dependencies (Python 3.11 - macOS, Windows)
if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows')
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Dependencies (Node.js)
if: "!contains(matrix.platform, 'linuxmusl')"
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.nodejs_version }}
architecture: ${{ matrix.nodejs_arch }}
- name: Checkout
uses: actions/checkout@v4
- name: Install
run: npm install --build-from-source
- name: Test
run: npm test
- name: Test packaging
run: |
npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
npm run clean
npm install --ignore-scripts
npm test
- name: Prebuild
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
env:
prebuild_upload: ${{ secrets.GITHUB_TOKEN }}
run: |
node -e "require('fs').cpSync('package.json', 'src/package.json')"
cd src
npx prebuild
github-runner-qemu:
permissions:
contents: write
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- platform: linux-arm
run_on_arch: armv6
nodejs_arch: armv6l
nodejs_hostname: unofficial-builds.nodejs.org
nodejs_version: "18.17.0"
nodejs_version_major: 18
- platform: linux-s390x
run_on_arch: s390x
nodejs_arch: s390x
nodejs_hostname: nodejs.org
nodejs_version: "18.17.0"
nodejs_version_major: 18
steps:
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: ${{ matrix.run_on_arch }}
distro: buster
env: |
prebuild_upload: "${{ startsWith(github.ref, 'refs/tags/') && secrets.GITHUB_TOKEN || '' }}"
run: |
apt-get update
apt-get install -y curl g++ git libatomic1 make python3 xz-utils
mkdir /opt/nodejs
curl --silent https://${{ matrix.nodejs_hostname }}/download/release/v${{ matrix.nodejs_version}}/node-v${{ matrix.nodejs_version}}-linux-${{ matrix.nodejs_arch }}.tar.xz | tar xJC /opt/nodejs --strip-components=1
export PATH=$PATH:/opt/nodejs/bin
npm install --build-from-source
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
npm run clean
npm install --ignore-scripts
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
[[ -n $prebuild_upload ]] && cd src && ln -s ../package.json && npx prebuild || true
github-runner-emscripten:
permissions:
contents: write
name: wasm32 - prebuild
runs-on: ubuntu-22.04
container: "emscripten/emsdk:3.1.56"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Dependencies
run: apt-get update && apt-get install -y pkg-config
- name: Dependencies (Node.js)
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install
run: emmake npm install --build-from-source
- name: Verify emscripten versions match
run: |
EMSCRIPTEN_VERSION_LIBVIPS=$(node -p "require('@img/sharp-libvips-dev-wasm32/versions').emscripten")
EMSCRIPTEN_VERSION_SHARP=$(emcc -dumpversion)
echo "libvips built with emscripten $EMSCRIPTEN_VERSION_LIBVIPS"
echo "sharp built with emscripten $EMSCRIPTEN_VERSION_SHARP"
test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP"
- name: Test
run: emmake npm test
- name: Test packaging
run: |
emmake npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-wasm32=file:./npm/wasm32"
npm run clean
rm -rf node_modules/@img/sharp-linux-x64
npm install --cpu=wasm32
npm test
- name: Prebuild
if: startsWith(github.ref, 'refs/tags/')
env:
npm_config_nodedir: emscripten
prebuild_upload: ${{ secrets.GITHUB_TOKEN }}
run: cd src && ln -s ../package.json && emmake npx prebuild --platform=emscripten --arch=wasm32 --strip=0
174 changes: 174 additions & 0 deletions .github/workflows/npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
name: "CI: npm smoke test"

on:
push:
tags:
- "v**"

permissions: {}

jobs:
release-smoke-test:
name: "${{ github.ref_name }} ${{ matrix.name }}"
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- name: linux-x64-node-npm
runs-on: ubuntu-22.04
runtime: node
package-manager: npm
- name: linux-x64-node-pnpm
runs-on: ubuntu-22.04
runtime: node
package-manager: pnpm
- name: linux-x64-node-yarn
runs-on: ubuntu-22.04
runtime: node
package-manager: yarn
- name: linux-x64-node-yarn-pnp
runs-on: ubuntu-22.04
runtime: node
package-manager: yarn-pnp
- name: linux-x64-deno
runs-on: ubuntu-22.04
runtime: deno
- name: linux-x64-bun
runs-on: ubuntu-22.04
runtime: bun

- name: darwin-x64-node-npm
runs-on: macos-11
runtime: node
package-manager: npm
- name: darwin-x64-node-pnpm
runs-on: macos-11
runtime: node
package-manager: pnpm
- name: darwin-x64-node-yarn
runs-on: macos-11
runtime: node
package-manager: yarn
- name: darwin-x64-node-yarn-pnp
runs-on: macos-11
runtime: node
package-manager: yarn-pnp
- name: darwin-x64-deno
runs-on: macos-11
runtime: deno
- name: darwin-x64-bun
runs-on: macos-11
runtime: bun

- name: win32-x64-node-npm
runs-on: windows-2019
runtime: node
package-manager: npm
- name: win32-x64-node-pnpm
runs-on: windows-2019
runtime: node
package-manager: pnpm
- name: win32-x64-node-yarn
runs-on: windows-2019
runtime: node
package-manager: yarn
- name: win32-x64-node-yarn-pnp
runs-on: windows-2019
runtime: node
package-manager: yarn-pnp
- name: win32-x64-deno
runs-on: windows-2019
runtime: deno

steps:
- name: Install Node.js
if: ${{ matrix.runtime == 'node' }}
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
if: ${{ matrix.package-manager == 'pnpm' }}
uses: pnpm/action-setup@v2
with:
version: 8
- name: Install Deno
if: ${{ matrix.runtime == 'deno' }}
uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- name: Install Bun
if: ${{ matrix.runtime == 'bun' }}
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Version
id: version
uses: actions/github-script@v6
with:
script: |
core.setOutput('semver', context.ref.replace('refs/tags/v',''))
- name: Create package.json
uses: DamianReeves/write-file-action@v1.2
with:
path: package.json
contents: |
{
"dependencies": {
"sharp": "${{ steps.version.outputs.semver }}"
},
"type": "module"
}
- name: Create release.mjs
uses: DamianReeves/write-file-action@v1.2
with:
path: release.mjs
contents: |
import { deepStrictEqual } from 'node:assert';
import sharp from 'sharp';
deepStrictEqual(['.jpg', '.jpeg', '.jpe', '.jfif'], sharp.format.jpeg.input.fileSuffix);
- name: Run with Node.js + npm
if: ${{ matrix.package-manager == 'npm' }}
run: |
npm install --ignore-scripts
node release.mjs
- name: Run with Node.js + pnpm
if: ${{ matrix.package-manager == 'pnpm' }}
run: |
pnpm install --ignore-scripts
node release.mjs
- name: Run with Node.js + yarn
if: ${{ matrix.package-manager == 'yarn' }}
run: |
corepack enable
yarn set version stable
yarn config set enableImmutableInstalls false
yarn config set enableScripts false
yarn config set nodeLinker node-modules
yarn install
node release.mjs
- name: Run with Node.js + yarn pnp
if: ${{ matrix.package-manager == 'yarn-pnp' }}
run: |
corepack enable
yarn set version stable
yarn config set enableImmutableInstalls false
yarn config set enableScripts false
yarn config set nodeLinker pnp
yarn install
yarn node release.mjs
- name: Run with Deno
if: ${{ matrix.runtime == 'deno' }}
run: deno run --allow-read --allow-ffi release.mjs

- name: Run with Bun
if: ${{ matrix.runtime == 'bun' }}
run: |
bun install --ignore-scripts
bun release.mjs
12 changes: 5 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
build
src/build
src/node_modules
node_modules
/coverage
npm/*/*
!npm/*/package.json
test/bench/node_modules
test/fixtures/output*
test/fixtures/vips-properties.xml
test/leak/libvips.supp
test/saliency/report.json
test/saliency/Image*
test/saliency/[Uu]serData*
!test/saliency/userData.js
vendor
.gitattributes
.DS_Store
.nyc_output
.vscode/
7 changes: 7 additions & 0 deletions .mocharc.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"parallel": true,
"slow": 1000,
"timeout": 30000,
"require": "./test/beforeEach.js",
"spec": "./test/unit/*.js"
}
4 changes: 3 additions & 1 deletion .prebuildrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"include-regex": "(sharp\\.node|libvips-cpp\\.dll)",
"runtime": "napi",
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll)",
"prerelease": true,
"strip": true
}
139 changes: 0 additions & 139 deletions .travis.yml

This file was deleted.

40 changes: 21 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# sharp

<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@master/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">

The typical use case for this high speed Node.js module
The typical use case for this high speed Node-API module
is to convert large images in common formats to
smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.

It can be used with all JavaScript runtimes
that provide support for Node-API v9, including
Node.js (^18.17.0 or >= 20.3.0), Deno and Bun.

Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings
@@ -16,9 +20,17 @@ Lanczos resampling ensures quality is not sacrificed for speed.
As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available.

Most modern macOS, Windows and Linux systems running Node.js v10.16.0+
Most modern macOS, Windows and Linux systems
do not require any additional install or runtime dependencies.

## Documentation

Visit [sharp.pixelplumbing.com](https://sharp.pixelplumbing.com/) for complete
[installation instructions](https://sharp.pixelplumbing.com/install),
[API documentation](https://sharp.pixelplumbing.com/api-constructor),
[benchmark tests](https://sharp.pixelplumbing.com/performance) and
[changelog](https://sharp.pixelplumbing.com/changelog).

## Examples

```sh
@@ -43,6 +55,7 @@ sharp(inputBuffer)
sharp('input.jpg')
.rotate()
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
.then( data => { ... })
.catch( err => { ... });
@@ -84,25 +97,14 @@ readableStream
.pipe(writableStream);
```

[![Test Coverage](https://coveralls.io/repos/lovell/sharp/badge.svg?branch=master)](https://coveralls.io/r/lovell/sharp?branch=master)
[![N-API v3](https://img.shields.io/badge/N--API-v3-green.svg)](https://nodejs.org/dist/latest/docs/api/n-api.html#n_api_n_api_version_matrix)

### Documentation

Visit [sharp.pixelplumbing.com](https://sharp.pixelplumbing.com/) for complete
[installation instructions](https://sharp.pixelplumbing.com/install),
[API documentation](https://sharp.pixelplumbing.com/api-constructor),
[benchmark tests](https://sharp.pixelplumbing.com/performance) and
[changelog](https://sharp.pixelplumbing.com/changelog).

### Contributing
## Contributing

A [guide for contributors](https://github.com/lovell/sharp/blob/master/.github/CONTRIBUTING.md)
A [guide for contributors](https://github.com/lovell/sharp/blob/main/.github/CONTRIBUTING.md)
covers reporting bugs, requesting features and submitting code changes.

### Licensing
## Licensing

Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Lovell Fuller and contributors.
Copyright 2013 Lovell Fuller and others.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
26 changes: 0 additions & 26 deletions appveyor.yml

This file was deleted.

232 changes: 0 additions & 232 deletions binding.gyp

This file was deleted.

28 changes: 20 additions & 8 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# sharp

<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@master/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">

The typical use case for this high speed Node.js module
The typical use case for this high speed Node-API module
is to convert large images in common formats to
smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.

It can be used with all JavaScript runtimes
that provide support for Node-API v9, including
Node.js >= 18.17.0, Deno and Bun.

Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings
@@ -16,14 +20,14 @@ Lanczos resampling ensures quality is not sacrificed for speed.
As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available.

Most modern macOS, Windows and Linux systems running Node.js v10.16.0+
Most modern macOS, Windows and Linux systems
do not require any additional install or runtime dependencies.

### Formats

This module supports reading JPEG, PNG, WebP, TIFF, GIF and SVG images.
This module supports reading JPEG, PNG, WebP, GIF, AVIF, TIFF and SVG images.

Output images can be in JPEG, PNG, WebP and TIFF formats as well as uncompressed raw pixel data.
Output images can be in JPEG, PNG, WebP, GIF, AVIF and TIFF formats as well as uncompressed raw pixel data.

Streams, Buffer objects and the filesystem can be used for input and output.

@@ -50,6 +54,10 @@ no child processes are spawned and Promises/async/await are supported.

### Optimal

The features of `mozjpeg` and `pngquant` can be used
to optimise the file size of JPEG and PNG images respectively,
without having to invoke separate `imagemin` processes.

Huffman tables are optimised when generating JPEG output images
without having to use separate command line tools like
[jpegoptim](https://github.com/tjko/jpegoptim) and
@@ -59,14 +67,18 @@ PNG filtering is disabled by default,
which for diagrams and line art often produces the same result
as [pngcrush](https://pmt.sourceforge.io/pngcrush/).

The file size of animated GIF output is optimised
without having to use separate command line tools such as
[gifsicle](https://www.lcdf.org/gifsicle/).

### Contributing

A [guide for contributors](https://github.com/lovell/sharp/blob/master/.github/CONTRIBUTING.md)
A [guide for contributors](https://github.com/lovell/sharp/blob/main/.github/CONTRIBUTING.md)
covers reporting bugs, requesting features and submitting code changes.

### Licensing

Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Lovell Fuller and contributors.
Copyright 2013 Lovell Fuller and others.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
136 changes: 76 additions & 60 deletions docs/api-channel.md
Original file line number Diff line number Diff line change
@@ -1,120 +1,136 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## removeAlpha
> removeAlpha() ⇒ <code>Sharp</code>
Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.

### Examples
See also [flatten](/api-operation#flatten).


```javascript
**Example**
```js
sharp('rgba.png')
.removeAlpha()
.toFile('rgb.png', function(err, info) {
// rgb.png is a 3 channel image without an alpha channel
});
```

Returns **Sharp**

## ensureAlpha
> ensureAlpha([alpha]) ⇒ <code>Sharp</code>
Ensure alpha channel, if missing. The added alpha channel will be fully opaque. This is a no-op if the image already has an alpha channel.
Ensure the output image has an alpha transparency channel.
If missing, the added alpha channel will have the specified
transparency level, defaulting to fully-opaque (1).
This is a no-op if the image already has an alpha channel.

### Examples

```javascript
sharp('rgb.jpg')
.ensureAlpha()
.toFile('rgba.png', function(err, info) {
// rgba.png is a 4 channel image with a fully opaque alpha channel
});
```
**Throws**:

- <code>Error</code> Invalid alpha transparency level

**Since**: 0.21.2

Returns **Sharp**
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [alpha] | <code>number</code> | <code>1</code> | alpha transparency level (0=fully-transparent, 1=fully-opaque) |

**Meta**
**Example**
```js
// rgba.png will be a 4 channel image with a fully-opaque alpha channel
await sharp('rgb.jpg')
.ensureAlpha()
.toFile('rgba.png')
```
**Example**
```js
// rgba is a 4 channel image with a fully-transparent alpha channel
const rgba = await sharp(rgb)
.ensureAlpha(0)
.toBuffer();
```

- **since**: 0.21.2

## extractChannel
> extractChannel(channel) ⇒ <code>Sharp</code>
Extract a single channel from a multi-channel image.

### Parameters

- `channel` **([number][1] \| [string][2])** zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`.
**Throws**:

- <code>Error</code> Invalid channel

### Examples

```javascript
sharp(input)
| Param | Type | Description |
| --- | --- | --- |
| channel | <code>number</code> \| <code>string</code> | zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`. |

**Example**
```js
// green.jpg is a greyscale image containing the green channel of the input
await sharp(input)
.extractChannel('green')
.toColourspace('b-w')
.toFile('green.jpg', function(err, info) {
// info.channels === 1
// green.jpg is a greyscale image containing the green channel of the input
});
.toFile('green.jpg');
```
**Example**
```js
// red1 is the red value of the first pixel, red2 the second pixel etc.
const [red1, red2, ...] = await sharp(input)
.extractChannel(0)
.raw()
.toBuffer();
```

- Throws **[Error][3]** Invalid channel

Returns **Sharp**

## joinChannel
> joinChannel(images, options) ⇒ <code>Sharp</code>
Join one or more channels to the image.
The meaning of the added channels depends on the output colourspace, set with `toColourspace()`.
By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
Channel ordering follows vips convention:
- sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
- CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.

- sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
- CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.

Buffers may be any of the image formats supported by sharp: JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data.
Buffers may be any of the image formats supported by sharp.
For raw pixel input, the `options` object should contain a `raw` attribute, which follows the format of the attribute of the same name in the `sharp()` constructor.

### Parameters

- `images` **([Array][4]&lt;([string][2] \| [Buffer][5])> | [string][2] \| [Buffer][5])** one or more images (file paths, Buffers).
- `options` **[Object][6]** image options, see `sharp()` constructor.
**Throws**:

- <code>Error</code> Invalid parameters


- Throws **[Error][3]** Invalid parameters
| Param | Type | Description |
| --- | --- | --- |
| images | <code>Array.&lt;(string\|Buffer)&gt;</code> \| <code>string</code> \| <code>Buffer</code> | one or more images (file paths, Buffers). |
| options | <code>Object</code> | image options, see `sharp()` constructor. |


Returns **Sharp**

## bandbool
> bandbool(boolOp) ⇒ <code>Sharp</code>
Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image.

### Parameters

- `boolOp` **[string][2]** one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
**Throws**:

- <code>Error</code> Invalid parameters

### Examples

```javascript
| Param | Type | Description |
| --- | --- | --- |
| boolOp | <code>string</code> | one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively. |

**Example**
```js
sharp('3-channel-rgb-input.png')
.bandbool(sharp.bool.and)
.toFile('1-channel-output.png', function (err, info) {
// The output will be a single channel image where each pixel `P = R & G & B`.
// If `I(1,1) = [247, 170, 14] = [0b11110111, 0b10101010, 0b00001111]`
// then `O(1,1) = 0b11110111 & 0b10101010 & 0b00001111 = 0b00000010 = 2`.
});
```

- Throws **[Error][3]** Invalid parameters

Returns **Sharp**

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[5]: https://nodejs.org/api/buffer.html

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
```
132 changes: 100 additions & 32 deletions docs/api-colour.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## tint
> tint(tint) ⇒ <code>Sharp</code>
Tint the image using the provided chroma while preserving the image luminance.
Tint the image using the provided colour.
An alpha channel may be present and will be unchanged by the operation.

### Parameters

- `rgb` **([string][1] \| [Object][2])** parsed by the [color][3] module to extract chroma values.
**Throws**:

- <code>Error</code> Invalid parameter


| Param | Type | Description |
| --- | --- | --- |
| tint | <code>string</code> \| <code>Object</code> | Parsed by the [color](https://www.npmjs.org/package/color) module. |

- Throws **[Error][4]** Invalid parameter
**Example**
```js
const output = await sharp(input)
.tint({ r: 255, g: 240, b: 16 })
.toBuffer();
```

Returns **Sharp**

## greyscale
> greyscale([greyscale]) ⇒ <code>Sharp</code>
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.
@@ -23,57 +32,116 @@ This may be overridden by other sharp operations such as `toColourspace('b-w')`,
which will produce an output image containing one color channel.
An alpha channel may be present, and will be unchanged by the operation.

### Parameters

- `greyscale` **[Boolean][5]** (optional, default `true`)

Returns **Sharp**
| Param | Type | Default |
| --- | --- | --- |
| [greyscale] | <code>Boolean</code> | <code>true</code> |

**Example**
```js
const output = await sharp(input).greyscale().toBuffer();
```


## grayscale
> grayscale([grayscale]) ⇒ <code>Sharp</code>
Alternative spelling of `greyscale`.

### Parameters

- `grayscale` **[Boolean][5]** (optional, default `true`)

Returns **Sharp**
| Param | Type | Default |
| --- | --- | --- |
| [grayscale] | <code>Boolean</code> | <code>true</code> |

## toColourspace

Set the output colourspace.
By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.

### Parameters
## pipelineColourspace
> pipelineColourspace([colourspace]) ⇒ <code>Sharp</code>
- `colourspace` **[string][1]?** output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][6]
Set the pipeline colourspace.

The input image will be converted to the provided colourspace at the start of the pipeline.
All operations will use this colourspace before converting to the output colourspace,
as defined by [toColourspace](#tocolourspace).

- Throws **[Error][4]** Invalid parameters
This feature is experimental and has not yet been fully-tested with all operations.

Returns **Sharp**

## toColorspace
**Throws**:

- <code>Error</code> Invalid parameters

**Since**: 0.29.0

| Param | Type | Description |
| --- | --- | --- |
| [colourspace] | <code>string</code> | pipeline colourspace e.g. `rgb16`, `scrgb`, `lab`, `grey16` [...](https://github.com/libvips/libvips/blob/41cff4e9d0838498487a00623462204eb10ee5b8/libvips/iofuncs/enumtypes.c#L774) |

**Example**
```js
// Run pipeline in 16 bits per channel RGB while converting final result to 8 bits per channel sRGB.
await sharp(input)
.pipelineColourspace('rgb16')
.toColourspace('srgb')
.toFile('16bpc-pipeline-to-8bpc-output.png')
```


## pipelineColorspace
> pipelineColorspace([colorspace]) ⇒ <code>Sharp</code>
Alternative spelling of `pipelineColourspace`.

Alternative spelling of `toColourspace`.

### Parameters
**Throws**:

- `colorspace` **[string][1]?** output colorspace.
- <code>Error</code> Invalid parameters


- Throws **[Error][4]** Invalid parameters
| Param | Type | Description |
| --- | --- | --- |
| [colorspace] | <code>string</code> | pipeline colorspace. |

Returns **Sharp**

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
## toColourspace
> toColourspace([colourspace]) ⇒ <code>Sharp</code>
Set the output colourspace.
By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.


**Throws**:

- <code>Error</code> Invalid parameters


| Param | Type | Description |
| --- | --- | --- |
| [colourspace] | <code>string</code> | output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/3c0bfdf74ce1dc37a6429bed47fa76f16e2cd70a/libvips/iofuncs/enumtypes.c#L777-L794) |

**Example**
```js
// Output 16 bits per pixel RGB
await sharp(input)
.toColourspace('rgb16')
.toFile('16-bpp.png')
```


## toColorspace
> toColorspace([colorspace]) ⇒ <code>Sharp</code>
Alternative spelling of `toColourspace`.


[3]: https://www.npmjs.org/package/color
**Throws**:

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
- <code>Error</code> Invalid parameters

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[6]: https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L568
| Param | Type | Description |
| --- | --- | --- |
| [colorspace] | <code>string</code> | output colorspace. |
127 changes: 69 additions & 58 deletions docs/api-composite.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,85 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## composite
> composite(images) ⇒ <code>Sharp</code>
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.
If both `top` and `left` options are provided, they take precedence over `gravity`.

Any resize, rotate or extract operations in the same processing pipeline
will always be applied to the input image before composition.

The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
`dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
`xor`, `add`, `saturate`, `multiply`, `screen`, `overlay`, `darken`, `lighten`,
`colour-dodge`, `color-dodge`, `colour-burn`,`color-burn`,
`hard-light`, `soft-light`, `difference`, `exclusion`.

More information about blend modes can be found at
[https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode][1]
and [https://www.cairographics.org/operators/][2]

### Parameters

- `images` **[Array][3]&lt;[Object][4]>** Ordered list of images to composite
- `images[].input` **([Buffer][5] \| [String][6])?** Buffer containing image data, String containing the path to an image file, or Create object (see below)
- `images[].input.create` **[Object][4]?** describes a blank overlay to be created.
- `images[].input.create.width` **[Number][7]?**
- `images[].input.create.height` **[Number][7]?**
- `images[].input.create.channels` **[Number][7]?** 3-4
- `images[].input.create.background` **([String][6] \| [Object][4])?** parsed by the [color][8] module to extract values for red, green, blue and alpha.
- `images[].blend` **[String][6]** how to blend this image with the image below. (optional, default `'over'`)
- `images[].gravity` **[String][6]** gravity at which to place the overlay. (optional, default `'centre'`)
- `images[].top` **[Number][7]?** the pixel offset from the top edge.
- `images[].left` **[Number][7]?** the pixel offset from the left edge.
- `images[].tile` **[Boolean][9]** set to true to repeat the overlay image across the entire image with the given `gravity`. (optional, default `false`)
- `images[].premultiplied` **[Boolean][9]** set to true to avoid premultipling the image below. Equivalent to the `--premultiplied` vips option. (optional, default `false`)
- `images[].density` **[Number][7]** number representing the DPI for vector overlay image. (optional, default `72`)
- `images[].raw` **[Object][4]?** describes overlay when using raw pixel data.
- `images[].raw.width` **[Number][7]?**
- `images[].raw.height` **[Number][7]?**
- `images[].raw.channels` **[Number][7]?**

### Examples

```javascript
https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode
and https://www.cairographics.org/operators/


**Throws**:

- <code>Error</code> Invalid parameters

**Since**: 0.22.0

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| images | <code>Array.&lt;Object&gt;</code> | | Ordered list of images to composite |
| [images[].input] | <code>Buffer</code> \| <code>String</code> | | Buffer containing image data, String containing the path to an image file, or Create object (see below) |
| [images[].input.create] | <code>Object</code> | | describes a blank overlay to be created. |
| [images[].input.create.width] | <code>Number</code> | | |
| [images[].input.create.height] | <code>Number</code> | | |
| [images[].input.create.channels] | <code>Number</code> | | 3-4 |
| [images[].input.create.background] | <code>String</code> \| <code>Object</code> | | parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. |
| [images[].input.text] | <code>Object</code> | | describes a new text image to be created. |
| [images[].input.text.text] | <code>string</code> | | text to render as a UTF-8 string. It can contain Pango markup, for example `<i>Le</i>Monde`. |
| [images[].input.text.font] | <code>string</code> | | font name to render with. |
| [images[].input.text.fontfile] | <code>string</code> | | absolute filesystem path to a font file that can be used by `font`. |
| [images[].input.text.width] | <code>number</code> | <code>0</code> | integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries. |
| [images[].input.text.height] | <code>number</code> | <code>0</code> | integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0. |
| [images[].input.text.align] | <code>string</code> | <code>&quot;&#x27;left&#x27;&quot;</code> | text alignment (`'left'`, `'centre'`, `'center'`, `'right'`). |
| [images[].input.text.justify] | <code>boolean</code> | <code>false</code> | set this to true to apply justification to the text. |
| [images[].input.text.dpi] | <code>number</code> | <code>72</code> | the resolution (size) at which to render the text. Does not take effect if `height` is specified. |
| [images[].input.text.rgba] | <code>boolean</code> | <code>false</code> | set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for Pango markup features like `<span foreground="red">Red!</span>`. |
| [images[].input.text.spacing] | <code>number</code> | <code>0</code> | text line height in points. Will use the font line height if none is specified. |
| [images[].blend] | <code>String</code> | <code>&#x27;over&#x27;</code> | how to blend this image with the image below. |
| [images[].gravity] | <code>String</code> | <code>&#x27;centre&#x27;</code> | gravity at which to place the overlay. |
| [images[].top] | <code>Number</code> | | the pixel offset from the top edge. |
| [images[].left] | <code>Number</code> | | the pixel offset from the left edge. |
| [images[].tile] | <code>Boolean</code> | <code>false</code> | set to true to repeat the overlay image across the entire image with the given `gravity`. |
| [images[].premultiplied] | <code>Boolean</code> | <code>false</code> | set to true to avoid premultiplying the image below. Equivalent to the `--premultiplied` vips option. |
| [images[].density] | <code>Number</code> | <code>72</code> | number representing the DPI for vector overlay image. |
| [images[].raw] | <code>Object</code> | | describes overlay when using raw pixel data. |
| [images[].raw.width] | <code>Number</code> | | |
| [images[].raw.height] | <code>Number</code> | | |
| [images[].raw.channels] | <code>Number</code> | | |
| [images[].animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image. |
| [images[].failOn] | <code>string</code> | <code>&quot;&#x27;warning&#x27;&quot;</code> | @see [constructor parameters](/api-constructor#parameters) |
| [images[].limitInputPixels] | <code>number</code> \| <code>boolean</code> | <code>268402689</code> | @see [constructor parameters](/api-constructor#parameters) |

**Example**
```js
await sharp(background)
.composite([
{ input: layer1, gravity: 'northwest' },
{ input: layer2, gravity: 'southeast' },
])
.toFile('combined.png');
```
**Example**
```js
const output = await sharp('input.gif', { animated: true })
.composite([
{ input: 'overlay.png', tile: true, blend: 'saturate' }
])
.toBuffer();
```
**Example**
```js
sharp('input.png')
.rotate(180)
.resize(300)
@@ -55,32 +94,4 @@ sharp('input.png')
// onto orange background, composited with overlay.png with SE gravity,
// sharpened, with metadata, 90% quality WebP image data. Phew!
});
```

- Throws **[Error][10]** Invalid parameters

Returns **Sharp**

**Meta**

- **since**: 0.22.0

[1]: https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode

[2]: https://www.cairographics.org/operators/

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[5]: https://nodejs.org/api/buffer.html

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[8]: https://www.npmjs.org/package/color

[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
```
219 changes: 139 additions & 80 deletions docs/api-constructor.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,100 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## Sharp
> Sharp

**Emits**: <code>Sharp#event:info</code>, <code>Sharp#event:warning</code>
<a name="new_Sharp_new"></a>

### new
> new Sharp([input], [options])
Constructor factory to create an instance of `sharp`, to which further methods are chained.

JPEG, PNG, WebP or TIFF format image data can be streamed out from this object.
JPEG, PNG, WebP, GIF, AVIF or TIFF format image data can be streamed out from this object.
When using Stream based output, derived attributes are available from the `info` event.

Non-critical problems encountered during processing are emitted as `warning` events.

Implements the [stream.Duplex][1] class.

### Parameters

- `input` **([Buffer][2] \| [string][3])?** if present, can be
a Buffer containing JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data, or
a String containing the filesystem path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file.
JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
- `options` **[Object][4]?** if present, is an Object with optional attributes.
- `options.failOnError` **[boolean][5]** by default halt processing and raise an error when loading invalid images.
Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid. (optional, default `true`)
- `options.limitInputPixels` **([number][6] \| [boolean][5])** Do not process input images where the number of pixels
(width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). (optional, default `268402689`)
- `options.sequentialRead` **[boolean][5]** Set this to `true` to use sequential rather than random access where possible.
This can reduce memory usage and might improve performance on some systems. (optional, default `false`)
- `options.density` **[number][6]** number representing the DPI for vector images in the range 1 to 100000. (optional, default `72`)
- `options.pages` **[number][6]** number of pages to extract for multi-page input (GIF, TIFF, PDF), use -1 for all pages. (optional, default `1`)
- `options.page` **[number][6]** page number to start extracting from for multi-page input (GIF, TIFF, PDF), zero based. (optional, default `0`)
- `options.level` **[number][6]** level to extract from a multi-level input (OpenSlide), zero based. (optional, default `0`)
- `options.animated` **[boolean][5]** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default `false`)
- `options.raw` **[Object][4]?** describes raw pixel input image data. See `raw()` for pixel ordering.
- `options.raw.width` **[number][6]?**
- `options.raw.height` **[number][6]?**
- `options.raw.channels` **[number][6]?** 1-4
- `options.create` **[Object][4]?** describes a new image to be created.
- `options.create.width` **[number][6]?**
- `options.create.height` **[number][6]?**
- `options.create.channels` **[number][6]?** 3-4
- `options.create.background` **([string][3] \| [Object][4])?** parsed by the [color][7] module to extract values for red, green, blue and alpha.

### Examples

```javascript
Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.

When loading more than one page/frame of an animated image,
these are combined as a vertically-stacked "toilet roll" image
where the overall height is the `pageHeight` multiplied by the number of `pages`.

**Throws**:

- <code>Error</code> Invalid parameters


| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [input] | <code>Buffer</code> \| <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Uint8ClampedArray</code> \| <code>Int8Array</code> \| <code>Uint16Array</code> \| <code>Int16Array</code> \| <code>Uint32Array</code> \| <code>Int32Array</code> \| <code>Float32Array</code> \| <code>Float64Array</code> \| <code>string</code> | | if present, can be a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or a TypedArray containing raw pixel image data, or a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file. JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present. |
| [options] | <code>Object</code> | | if present, is an Object with optional attributes. |
| [options.failOn] | <code>string</code> | <code>&quot;&#x27;warning&#x27;&quot;</code> | When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort. |
| [options.limitInputPixels] | <code>number</code> \| <code>boolean</code> | <code>268402689</code> | Do not process input images where the number of pixels (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted. An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). |
| [options.unlimited] | <code>boolean</code> | <code>false</code> | Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF). |
| [options.sequentialRead] | <code>boolean</code> | <code>true</code> | Set this to `false` to use random access rather than sequential read. Some operations will do this automatically. |
| [options.density] | <code>number</code> | <code>72</code> | number representing the DPI for vector images in the range 1 to 100000. |
| [options.ignoreIcc] | <code>number</code> | <code>false</code> | should the embedded ICC profile, if any, be ignored. |
| [options.pages] | <code>number</code> | <code>1</code> | Number of pages to extract for multi-page input (GIF, WebP, TIFF), use -1 for all 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.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.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.width] | <code>number</code> | | integral number of pixels wide. |
| [options.raw.height] | <code>number</code> | | integral number of pixels high. |
| [options.raw.channels] | <code>number</code> | | integral number of channels, between 1 and 4. |
| [options.raw.premultiplied] | <code>boolean</code> | | specifies that the raw input has already been premultiplied, set to `true` to avoid sharp premultiplying the image. (optional, default `false`) |
| [options.create] | <code>Object</code> | | describes a new image to be created. |
| [options.create.width] | <code>number</code> | | integral number of pixels wide. |
| [options.create.height] | <code>number</code> | | integral number of pixels high. |
| [options.create.channels] | <code>number</code> | | integral number of channels, either 3 (RGB) or 4 (RGBA). |
| [options.create.background] | <code>string</code> \| <code>Object</code> | | parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. |
| [options.create.noise] | <code>Object</code> | | describes a noise to be created. |
| [options.create.noise.type] | <code>string</code> | | type of generated noise, currently only `gaussian` is supported. |
| [options.create.noise.mean] | <code>number</code> | | mean of pixels in generated noise. |
| [options.create.noise.sigma] | <code>number</code> | | standard deviation of pixels in generated noise. |
| [options.text] | <code>Object</code> | | describes a new text image to be created. |
| [options.text.text] | <code>string</code> | | text to render as a UTF-8 string. It can contain Pango markup, for example `<i>Le</i>Monde`. |
| [options.text.font] | <code>string</code> | | font name to render with. |
| [options.text.fontfile] | <code>string</code> | | absolute filesystem path to a font file that can be used by `font`. |
| [options.text.width] | <code>number</code> | <code>0</code> | Integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries. |
| [options.text.height] | <code>number</code> | <code>0</code> | Maximum integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0. |
| [options.text.align] | <code>string</code> | <code>&quot;&#x27;left&#x27;&quot;</code> | Alignment style for multi-line text (`'left'`, `'centre'`, `'center'`, `'right'`). |
| [options.text.justify] | <code>boolean</code> | <code>false</code> | set this to true to apply justification to the text. |
| [options.text.dpi] | <code>number</code> | <code>72</code> | the resolution (size) at which to render the text. Does not take effect if `height` is specified. |
| [options.text.rgba] | <code>boolean</code> | <code>false</code> | set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for pango markup features like `<span foreground="red">Red!</span>`. |
| [options.text.spacing] | <code>number</code> | <code>0</code> | text line height in points. Will use the font line height if none is specified. |
| [options.text.wrap] | <code>string</code> | <code>&quot;&#x27;word&#x27;&quot;</code> | word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none'. |

**Example**
```js
sharp('input.jpg')
.resize(300, 200)
.toFile('output.jpg', function(err) {
// output.jpg is a 300 pixels wide and 200 pixels high image
// containing a scaled and cropped version of input.jpg
});
```

```javascript
// Read image data from readableStream,
**Example**
```js
// Read image data from remote URL,
// resize to 300 pixels wide,
// emit an 'info' event with calculated dimensions
// and finally write image data to writableStream
var transformer = sharp()
const { body } = fetch('https://...');
const readableStream = Readable.fromWeb(body);
const transformer = sharp()
.resize(300)
.on('info', function(info) {
console.log('Image height is ' + info.height);
.on('info', ({ height }) => {
console.log(`Image height is ${height}`);
});
readableStream.pipe(transformer).pipe(writableStream);
```

```javascript
// Create a blank 300x200 PNG image of semi-transluent red pixels
**Example**
```js
// Create a blank 300x200 PNG image of semi-translucent red pixels
sharp({
create: {
width: 300,
@@ -78,41 +107,91 @@ sharp({
.toBuffer()
.then( ... );
```

```javascript
**Example**
```js
// Convert an animated GIF to an animated WebP
await sharp('in.gif', { animated: true }).toFile('out.webp');
```
**Example**
```js
// Read a raw array of pixels and save it to a png
const input = Uint8Array.from([255, 255, 255, 0, 0, 0]); // or Uint8ClampedArray
const image = sharp(input, {
// because the input does not contain its dimensions or how many channels it has
// we need to specify it in the constructor options
raw: {
width: 2,
height: 1,
channels: 3
}
});
await image.toFile('my-two-pixels.png');
```
**Example**
```js
// Generate RGB Gaussian noise
await sharp({
create: {
width: 300,
height: 200,
channels: 3,
noise: {
type: 'gaussian',
mean: 128,
sigma: 30
}
}
}).toFile('noise.png');
```
**Example**
```js
// Generate an image from text
await sharp({
text: {
text: 'Hello, world!',
width: 400, // max width
height: 300 // max height
}
}).toFile('text_bw.png');
```
**Example**
```js
// Generate an rgba image from text using pango markup and font
await sharp({
text: {
text: '<span foreground="red">Red!</span><span background="cyan">blue</span>',
font: 'sans',
rgba: true,
dpi: 300
}
}).toFile('text_rgba.png');
```

- Throws **[Error][8]** Invalid parameters

Returns **[Sharp][9]**

## clone
> clone() ⇒ [<code>Sharp</code>](#Sharp)
Take a "snapshot" of the Sharp instance, returning a new instance.
Cloned instances inherit the input of their parent instance.
This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream.

### Examples

```javascript
**Example**
```js
const pipeline = sharp().rotate();
pipeline.clone().resize(800, 600).pipe(firstWritableStream);
pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream);
readableStream.pipe(pipeline);
// firstWritableStream receives auto-rotated, resized readableStream
// secondWritableStream receives auto-rotated, extracted region of readableStream
```

```javascript
**Example**
```js
// Create a pipeline that will download an image, resize it and format it to different files
// Using Promises to know when the pipeline is complete
const fs = require("fs");
const got = require("got");
const sharpStream = sharp({
failOnError: false
});
const sharpStream = sharp({ failOn: 'none' });

const promises = [];

@@ -139,7 +218,7 @@ promises.push(
.toFile("optimized-500.webp")
);

// https://github.com/sindresorhus/got#gotstreamurl-options
// https://github.com/sindresorhus/got/blob/main/documentation/3-streams.md
got.stream("https://www.example.com/some-file.jpg").pipe(sharpStream);

Promise.all(promises)
@@ -152,24 +231,4 @@ Promise.all(promises)
fs.unlinkSync("optimized-500.webp");
} catch (e) {}
});
```

Returns **[Sharp][9]**

[1]: http://nodejs.org/api/stream.html#stream_class_stream_duplex

[2]: https://nodejs.org/api/buffer.html

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[7]: https://www.npmjs.org/package/color

[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[9]: #sharp
```
178 changes: 103 additions & 75 deletions docs/api-input.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,60 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## metadata
> metadata([callback]) ⇒ <code>Promise.&lt;Object&gt;</code> \| <code>Sharp</code>
Fast access to (uncached) image metadata without decoding any compressed pixel data.

This is read from the header of the input image.
It does not take into consideration any operations to be applied to the output image,
such as resize or rotate.

Dimensions in the response will respect the `page` and `pages` properties of the
[constructor parameters](/api-constructor#parameters).

Fast access to (uncached) image metadata without decoding any compressed image data.
A `Promise` is returned when `callback` is not provided.

- `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
- `size`: Total size of image in bytes, for Stream and Buffer input only
- `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
- `height`: Number of pixels high (EXIF orientation is not taken into consideration)
- `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...][1]
- `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
- `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...][2]
- `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
- `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
- `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.
- `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.
- `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
- `hasProfile`: Boolean indicating the presence of an embedded ICC profile
- `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
- `orientation`: Number value of the EXIF Orientation header, if present
- `exif`: Buffer containing raw EXIF data, if present
- `icc`: Buffer containing raw [ICC][3] profile data, if present
- `iptc`: Buffer containing raw IPTC data, if present
- `xmp`: Buffer containing raw XMP data, if present
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present

### Parameters

- `callback` **[Function][4]?** called with the arguments `(err, metadata)`

### Examples

```javascript
- `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
- `size`: Total size of image in bytes, for Stream and Buffer input only
- `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
- `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
- `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/VipsImage.html#VipsInterpretation)
- `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
- `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/VipsImage.html#VipsBandFormat)
- `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
- `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
- `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.
- `paletteBitDepth`: Bit depth of palette-based image (GIF, PNG).
- `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.
- `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
- `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
- `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
- `hasProfile`: Boolean indicating the presence of an embedded ICC profile
- `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
- `orientation`: Number value of the EXIF Orientation header, if present
- `exif`: Buffer containing raw EXIF data, if present
- `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
- `iptc`: Buffer containing raw IPTC data, if present
- `xmp`: Buffer containing raw XMP data, if present
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
- `formatMagick`: String containing format for images loaded via *magick



| Param | Type | Description |
| --- | --- | --- |
| [callback] | <code>function</code> | called with the arguments `(err, metadata)` |

**Example**
```js
const metadata = await sharp(input).metadata();
```
**Example**
```js
const image = sharp(inputJpg);
image
.metadata()
@@ -50,60 +68,70 @@ image
// data contains a WebP image half the width and height of the original JPEG
});
```
**Example**
```js
// Based on EXIF rotation metadata, get the right-side-up width and height:

const size = getNormalSize(await sharp(input).metadata());

function getNormalSize({ width, height, orientation }) {
return (orientation || 0) >= 5
? { width: height, height: width }
: { width, height };
}
```

Returns **([Promise][5]&lt;[Object][6]> | Sharp)**

## stats
> stats([callback]) ⇒ <code>Promise.&lt;Object&gt;</code>
Access to pixel-derived image statistics for every channel in the image.
A `Promise` is returned when `callback` is not provided.

- `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains
- `min` (minimum value in the channel)
- `max` (maximum value in the channel)
- `sum` (sum of all values in a channel)
- `squaresSum` (sum of squared values in a channel)
- `mean` (mean of the values in a channel)
- `stdev` (standard deviation for the values in a channel)
- `minX` (x-coordinate of one of the pixel where the minimum lies)
- `minY` (y-coordinate of one of the pixel where the minimum lies)
- `maxX` (x-coordinate of one of the pixel where the maximum lies)
- `maxY` (y-coordinate of one of the pixel where the maximum lies)
- `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
- `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental)
- `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any (experimental)
- `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram (experimental)

### Parameters

- `callback` **[Function][4]?** called with the arguments `(err, stats)`

### Examples

```javascript
- `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains
- `min` (minimum value in the channel)
- `max` (maximum value in the channel)
- `sum` (sum of all values in a channel)
- `squaresSum` (sum of squared values in a channel)
- `mean` (mean of the values in a channel)
- `stdev` (standard deviation for the values in a channel)
- `minX` (x-coordinate of one of the pixel where the minimum lies)
- `minY` (y-coordinate of one of the pixel where the minimum lies)
- `maxX` (x-coordinate of one of the pixel where the maximum lies)
- `maxY` (y-coordinate of one of the pixel where the maximum lies)
- `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
- `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any.
- `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any.
- `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram.

**Note**: Statistics are derived from the original input image. Any operations performed on the image must first be
written to a buffer in order to run `stats` on the result (see third example).



| Param | Type | Description |
| --- | --- | --- |
| [callback] | <code>function</code> | called with the arguments `(err, stats)` |

**Example**
```js
const image = sharp(inputJpg);
image
.stats()
.then(function(stats) {
// stats contains the channel-wise statistics array and the isOpaque value
});
```

```javascript
**Example**
```js
const { entropy, sharpness, dominant } = await sharp(input).stats();
const { r, g, b } = dominant;
```

Returns **[Promise][5]&lt;[Object][6]>**

[1]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation

[2]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat

[3]: https://www.npmjs.com/package/icc

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
**Example**
```js
const image = sharp(input);
// store intermediate result
const part = await image.extract(region).toBuffer();
// create new instance to obtain statistics of extracted region
const stats = await sharp(part).stats();
```
616 changes: 463 additions & 153 deletions docs/api-operation.md

Large diffs are not rendered by default.

832 changes: 629 additions & 203 deletions docs/api-output.md

Large diffs are not rendered by default.

292 changes: 178 additions & 114 deletions docs/api-resize.md

Large diffs are not rendered by default.

218 changes: 156 additions & 62 deletions docs/api-utility.md
Original file line number Diff line number Diff line change
@@ -1,139 +1,233 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
## versions
> versions
An Object containing the version numbers of sharp, libvips
and (when using prebuilt binaries) its dependencies.


**Example**
```js
console.log(sharp.versions);
```


## interpolators
> interpolators : <code>enum</code>
An Object containing the available interpolators and their proper values


**Read only**: true
**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| nearest | <code>string</code> | <code>&quot;nearest&quot;</code> | [Nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation). Suitable for image enlargement only. |
| bilinear | <code>string</code> | <code>&quot;bilinear&quot;</code> | [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation). Faster than bicubic but with less smooth results. |
| bicubic | <code>string</code> | <code>&quot;bicubic&quot;</code> | [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) (the default). |
| locallyBoundedBicubic | <code>string</code> | <code>&quot;lbb&quot;</code> | [LBB interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/lbb.cpp#L100). Prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" but typically reduces performance by a factor of 2. |
| nohalo | <code>string</code> | <code>&quot;nohalo&quot;</code> | [Nohalo interpolation](http://eprints.soton.ac.uk/268086/). Prevents acutance but typically reduces performance by a factor of 3. |
| vertexSplitQuadraticBasisSpline | <code>string</code> | <code>&quot;vsqbs&quot;</code> | [VSQBS interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/vsqbs.cpp#L48). Prevents "staircasing" when enlarging. |



## format
> format ⇒ <code>Object</code>
An Object containing nested boolean values representing the available input and output formats/methods.

### Examples

```javascript
**Example**
```js
console.log(sharp.format);
```

Returns **[Object][1]**

## versions
## queue
> queue
An Object containing the version numbers of libvips and its dependencies.
An EventEmitter that emits a `change` event when a task is either:
- queued, waiting for _libuv_ to provide a worker thread
- complete

### Examples

```javascript
console.log(sharp.versions);
**Example**
```js
sharp.queue.on('change', function(queueLength) {
console.log('Queue contains ' + queueLength + ' task(s)');
});
```


## cache
> cache([options]) ⇒ <code>Object</code>
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.
This method always returns cache statistics,
useful for determining how much working memory is required for a particular task.

### Parameters

- `options` **([Object][1] \| [boolean][2])** Object with the following attributes, or boolean where true uses default cache settings and false removes all caching (optional, default `true`)
- `options.memory` **[number][3]** is the maximum memory in MB to use for this cache (optional, default `50`)
- `options.files` **[number][3]** is the maximum number of files to hold open (optional, default `20`)
- `options.items` **[number][3]** is the maximum number of operations to cache (optional, default `100`)

### Examples
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> \| <code>boolean</code> | <code>true</code> | Object with the following attributes, or boolean where true uses default cache settings and false removes all caching |
| [options.memory] | <code>number</code> | <code>50</code> | is the maximum memory in MB to use for this cache |
| [options.files] | <code>number</code> | <code>20</code> | is the maximum number of files to hold open |
| [options.items] | <code>number</code> | <code>100</code> | is the maximum number of operations to cache |

```javascript
**Example**
```js
const stats = sharp.cache();
```

```javascript
**Example**
```js
sharp.cache( { items: 200 } );
sharp.cache( { files: 0 } );
sharp.cache(false);
```

Returns **[Object][1]**

## concurrency
> concurrency([concurrency]) ⇒ <code>number</code>
Gets or, when a concurrency is provided, sets
the number of threads _libvips'_ should create to process each image.
The default value is the number of CPU cores.
A value of `0` will reset to this default.

The maximum number of images that can be processed in parallel
is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
the maximum number of threads _libvips_ should use to process _each image_.
These are from a thread pool managed by glib,
which helps avoid the overhead of creating new threads.

This method always returns the current concurrency.

### Parameters
The default value is the number of CPU cores,
except when using glibc-based Linux without jemalloc,
where the default is `1` to help reduce memory fragmentation.

- `concurrency` **[number][3]?**
A value of `0` will reset this to the number of CPU cores.

### Examples
Some image format libraries spawn additional threads,
e.g. libaom manages its own 4 threads when encoding AVIF images,
and these are independent of the value set here.

```javascript
const threads = sharp.concurrency(); // 4
sharp.concurrency(2); // 2
sharp.concurrency(0); // 4
```
The maximum number of images that sharp can process in parallel
is controlled by libuv's `UV_THREADPOOL_SIZE` environment variable,
which defaults to 4.

Returns **[number][3]** concurrency
https://nodejs.org/api/cli.html#uv_threadpool_sizesize

## queue
For example, by default, a machine with 8 CPU cores will process
4 images in parallel and use up to 8 threads per image,
so there will be up to 32 concurrent threads.

An EventEmitter that emits a `change` event when a task is either:

- queued, waiting for _libuv_ to provide a worker thread
- complete
**Returns**: <code>number</code> - concurrency

### Examples
| Param | Type |
| --- | --- |
| [concurrency] | <code>number</code> |

```javascript
sharp.queue.on('change', function(queueLength) {
console.log('Queue contains ' + queueLength + ' task(s)');
});
**Example**
```js
const threads = sharp.concurrency(); // 4
sharp.concurrency(2); // 2
sharp.concurrency(0); // 4
```


## counters
> counters() ⇒ <code>Object</code>
Provides access to internal task counters.
- queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
- process is the number of resize tasks currently being processed.

- queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
- process is the number of resize tasks currently being processed.

### Examples

```javascript
**Example**
```js
const counters = sharp.counters(); // { queue: 2, process: 4 }
```

Returns **[Object][1]**

## simd
> simd([simd]) ⇒ <code>boolean</code>
Get and set use of SIMD vector unit instructions.
Requires libvips to have been compiled with liborc support.
Requires libvips to have been compiled with highway support.

Improves the performance of `resize`, `blur` and `sharpen` operations
by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM NEON.

### Parameters

- `simd` **[boolean][2]** (optional, default `true`)

### Examples
| Param | Type | Default |
| --- | --- | --- |
| [simd] | <code>boolean</code> | <code>true</code> |

```javascript
**Example**
```js
const simd = sharp.simd();
// simd is `true` if the runtime use of liborc is currently enabled
// simd is `true` if the runtime use of highway is currently enabled
```

```javascript
**Example**
```js
const simd = sharp.simd(false);
// prevent libvips from using liborc at runtime
// prevent libvips from using highway at runtime
```

Returns **[boolean][2]**

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
## block
> block(options)
Block libvips operations at runtime.

This is in addition to the `VIPS_BLOCK_UNTRUSTED` environment variable,
which when set will block all "untrusted" operations.

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
**Since**: 0.32.4

| Param | Type | Description |
| --- | --- | --- |
| options | <code>Object</code> | |
| options.operation | <code>Array.&lt;string&gt;</code> | List of libvips low-level operation names to block. |

**Example** *(Block all TIFF input.)*
```js
sharp.block({
operation: ['VipsForeignLoadTiff']
});
```


## unblock
> unblock(options)
Unblock libvips operations at runtime.

This is useful for defining a list of allowed operations.


**Since**: 0.32.4

| Param | Type | Description |
| --- | --- | --- |
| options | <code>Object</code> | |
| options.operation | <code>Array.&lt;string&gt;</code> | List of libvips low-level operation names to unblock. |

**Example** *(Block all input except WebP from the filesystem.)*
```js
sharp.block({
operation: ['VipsForeignLoad']
});
sharp.unblock({
operation: ['VipsForeignLoadWebpFile']
});
```
**Example** *(Block all input except JPEG and PNG from a Buffer or Stream.)*
```js
sharp.block({
operation: ['VipsForeignLoad']
});
sharp.unblock({
operation: ['VipsForeignLoadJpegBuffer', 'VipsForeignLoadPngBuffer']
});
```
38 changes: 38 additions & 0 deletions docs/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0

'use strict';

const fs = require('fs').promises;
const path = require('path');
const jsdoc2md = require('jsdoc-to-markdown');

[
'constructor',
'input',
'resize',
'composite',
'operation',
'colour',
'channel',
'output',
'utility'
].forEach(async (m) => {
const input = path.join('lib', `${m}.js`);
const output = path.join('docs', `api-${m}.md`);

const ast = await jsdoc2md.getTemplateData({ files: input });
const markdown = await jsdoc2md.render({
data: ast,
'global-index-format': 'none',
'module-index-format': 'none'
});

const cleanMarkdown = markdown
.replace(/(## )([A-Za-z0-9]+)([^\n]*)/g, '$1$2\n> $2$3\n') // simplify headings to match those of documentationjs, ensures existing URLs work
.replace(/<a name="[A-Za-z0-9+]+"><\/a>/g, '') // remove anchors, let docute add these (at markdown to HTML render time)
.replace(/\*\*Kind\*\*: global[^\n]+/g, '') // remove all "global" Kind labels (requires JSDoc refactoring)
.trim();

await fs.writeFile(output, cleanMarkdown);
});
Loading