mirror of
https://github.com/lovell/sharp.git
synced 2026-02-10 08:36:15 +01:00
Compare commits
4 Commits
006d37b2d0
...
4b1680c312
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b1680c312 | ||
|
|
2346722c0d | ||
|
|
a5e726002c | ||
|
|
d161e45e06 |
@@ -326,3 +326,6 @@ GitHub: https://github.com/tpatel
|
||||
|
||||
Name: Maël Nison
|
||||
GitHub: https://github.com/arcanis
|
||||
|
||||
Name: Dmytro Tiapukhin
|
||||
GitHub: https://github.com/eddienubes
|
||||
|
||||
@@ -284,6 +284,7 @@ The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` pro
|
||||
| [options.background] | <code>string</code> \| <code>Object</code> | <code>"'top-left pixel'"</code> | Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel. |
|
||||
| [options.threshold] | <code>number</code> | <code>10</code> | Allowed difference from the above colour, a positive number. |
|
||||
| [options.lineArt] | <code>boolean</code> | <code>false</code> | Does the input more closely resemble line art (e.g. vector) rather than being photographic? |
|
||||
| [options.margin] | <code>number</code> | <code>0</code> | Leave a margin around trimmed content, value is in pixels. |
|
||||
|
||||
**Example**
|
||||
```js
|
||||
@@ -320,4 +321,13 @@ const output = await sharp(input)
|
||||
threshold: 42,
|
||||
})
|
||||
.toBuffer();
|
||||
```
|
||||
**Example**
|
||||
```js
|
||||
// Trim image leaving (up to) a 10 pixel margin around the trimmed content.
|
||||
const output = await sharp(input)
|
||||
.trim({
|
||||
margin: 10
|
||||
})
|
||||
.toBuffer();
|
||||
```
|
||||
@@ -16,6 +16,8 @@ slug: changelog/v0.35.0
|
||||
|
||||
* Breaking: Remove deprecated properties from `sharpen` operation.
|
||||
|
||||
* Breaking: Rename `format.jp2k` as `format.jp2` for API consistency.
|
||||
|
||||
* Upgrade to libvips v8.18.0 for upstream bug fixes.
|
||||
|
||||
* Deprecate Windows 32-bit (win32-ia32) prebuilt binaries.
|
||||
@@ -29,4 +31,11 @@ slug: changelog/v0.35.0
|
||||
* Add `toUint8Array` for output image as a `TypedArray` backed by a transferable `ArrayBuffer`.
|
||||
[#4355](https://github.com/lovell/sharp/issues/4355)
|
||||
|
||||
* TypeScript: Ensure `FormatEnum` keys match reality.
|
||||
[#4475](https://github.com/lovell/sharp/issues/4475)
|
||||
|
||||
* Add `margin` option to `trim` operation.
|
||||
[#4480](https://github.com/lovell/sharp/issues/4480)
|
||||
[@eddienubes](https://github.com/eddienubes)
|
||||
|
||||
* Add WebP `exact` option for control over transparent pixel colour values.
|
||||
|
||||
@@ -278,6 +278,7 @@ const Sharp = function (input, options) {
|
||||
trimBackground: [],
|
||||
trimThreshold: -1,
|
||||
trimLineArt: false,
|
||||
trimMargin: 0,
|
||||
dilateWidth: 0,
|
||||
erodeWidth: 0,
|
||||
gamma: 0,
|
||||
|
||||
10
lib/index.d.ts
vendored
10
lib/index.d.ts
vendored
@@ -840,7 +840,7 @@ declare namespace sharp {
|
||||
* @returns A sharp instance that can be used to chain operations
|
||||
*/
|
||||
toFormat(
|
||||
format: keyof FormatEnum | AvailableFormatInfo,
|
||||
format: keyof FormatEnum | AvailableFormatInfo | "avif",
|
||||
options?:
|
||||
| OutputOptions
|
||||
| JpegOptions
|
||||
@@ -1606,6 +1606,8 @@ declare namespace sharp {
|
||||
threshold?: number | undefined;
|
||||
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
||||
lineArt?: boolean | undefined;
|
||||
/** Leave a margin around trimmed content, value is in pixels. (optional, default 0) */
|
||||
margin?: number | undefined;
|
||||
}
|
||||
|
||||
interface RawOptions {
|
||||
@@ -1911,16 +1913,13 @@ declare namespace sharp {
|
||||
}
|
||||
|
||||
interface FormatEnum {
|
||||
avif: AvailableFormatInfo;
|
||||
dcraw: AvailableFormatInfo;
|
||||
dz: AvailableFormatInfo;
|
||||
exr: AvailableFormatInfo;
|
||||
fits: AvailableFormatInfo;
|
||||
gif: AvailableFormatInfo;
|
||||
heif: AvailableFormatInfo;
|
||||
input: AvailableFormatInfo;
|
||||
jpeg: AvailableFormatInfo;
|
||||
jpg: AvailableFormatInfo;
|
||||
jp2: AvailableFormatInfo;
|
||||
jxl: AvailableFormatInfo;
|
||||
magick: AvailableFormatInfo;
|
||||
@@ -1932,8 +1931,7 @@ declare namespace sharp {
|
||||
raw: AvailableFormatInfo;
|
||||
svg: AvailableFormatInfo;
|
||||
tiff: AvailableFormatInfo;
|
||||
tif: AvailableFormatInfo;
|
||||
v: AvailableFormatInfo;
|
||||
vips: AvailableFormatInfo;
|
||||
webp: AvailableFormatInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ function toFile (fileOut, callback) {
|
||||
err = new Error('Missing output file path');
|
||||
} else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) {
|
||||
err = new Error('Cannot use same file for input and output');
|
||||
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
|
||||
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2.output.file) {
|
||||
err = errJp2Save();
|
||||
}
|
||||
if (err) {
|
||||
@@ -950,7 +950,7 @@ function gif (options) {
|
||||
*/
|
||||
function jp2 (options) {
|
||||
/* node:coverage ignore next 41 */
|
||||
if (!this.constructor.format.jp2k.output.buffer) {
|
||||
if (!this.constructor.format.jp2.output.buffer) {
|
||||
throw errJp2Save();
|
||||
}
|
||||
if (is.object(options)) {
|
||||
|
||||
@@ -540,10 +540,19 @@ function extract (options) {
|
||||
* })
|
||||
* .toBuffer();
|
||||
*
|
||||
* @example
|
||||
* // Trim image leaving (up to) a 10 pixel margin around the trimmed content.
|
||||
* const output = await sharp(input)
|
||||
* .trim({
|
||||
* margin: 10
|
||||
* })
|
||||
* .toBuffer();
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {string|Object} [options.background='top-left pixel'] - Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
|
||||
* @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number.
|
||||
* @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic?
|
||||
* @param {number} [options.margin=0] - Leave a margin around trimmed content, value is in pixels.
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
@@ -564,6 +573,13 @@ function trim (options) {
|
||||
if (is.defined(options.lineArt)) {
|
||||
this._setBooleanOption('trimLineArt', options.lineArt);
|
||||
}
|
||||
if (is.defined(options.margin)) {
|
||||
if (is.integer(options.margin) && options.margin >= 0) {
|
||||
this.options.trimMargin = options.margin;
|
||||
} else {
|
||||
throw is.invalidParameterError('margin', 'positive integer', options.margin);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw is.invalidParameterError('trim', 'object', options);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const format = sharp.format();
|
||||
format.heif.output.alias = ['avif', 'heic'];
|
||||
format.jpeg.output.alias = ['jpe', 'jpg'];
|
||||
format.tiff.output.alias = ['tif'];
|
||||
format.jp2k.output.alias = ['j2c', 'j2k', 'jp2', 'jpx'];
|
||||
format.jp2.output.alias = ['j2c', 'j2k', 'jp2', 'jpx'];
|
||||
|
||||
/**
|
||||
* An Object containing the available interpolators and their proper values
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-darwin-arm64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with macOS 64-bit ARM",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-darwin-x64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with macOS x64",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-arm",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-arm": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-arm64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) 64-bit ARM",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-ppc64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) ppc64",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-riscv64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) RISC-V 64-bit",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-s390x",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) s390x",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-x64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) x64",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linux-x64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linuxmusl-arm64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (musl) 64-bit ARM",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linuxmusl-x64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Linux (musl) x64",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.1"
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.2"
|
||||
},
|
||||
"files": [
|
||||
"index.cjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"private": "true",
|
||||
"workspaces": [
|
||||
"darwin-arm64",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-wasm32",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with wasm32",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-arm64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Windows 64-bit ARM",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-ia32",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Windows x86 (deprecated)",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-x64",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"description": "Prebuilt sharp for use with Windows x64",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
|
||||
63
package.json
63
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
||||
"version": "0.34.5",
|
||||
"version": "0.35.0-rc.0",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"contributors": [
|
||||
@@ -89,7 +89,8 @@
|
||||
"Lachlan Newman <lachnewman007@gmail.com>",
|
||||
"Dennis Beatty <dennis@dcbeatty.com>",
|
||||
"Ingvar Stepanyan <me@rreverser.com>",
|
||||
"Don Denton <don@happycollision.com>"
|
||||
"Don Denton <don@happycollision.com>",
|
||||
"Dmytro Tiapukhin <cool.gegeg@gmail.com>"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "node install/build.js",
|
||||
@@ -143,40 +144,40 @@
|
||||
"semver": "^7.7.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.34.5",
|
||||
"@img/sharp-darwin-x64": "0.34.5",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-arm": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linux-x64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.1",
|
||||
"@img/sharp-linux-arm": "0.34.5",
|
||||
"@img/sharp-linux-arm64": "0.34.5",
|
||||
"@img/sharp-linux-ppc64": "0.34.5",
|
||||
"@img/sharp-linux-riscv64": "0.34.5",
|
||||
"@img/sharp-linux-s390x": "0.34.5",
|
||||
"@img/sharp-linux-x64": "0.34.5",
|
||||
"@img/sharp-linuxmusl-arm64": "0.34.5",
|
||||
"@img/sharp-linuxmusl-x64": "0.34.5",
|
||||
"@img/sharp-wasm32": "0.34.5",
|
||||
"@img/sharp-win32-arm64": "0.34.5",
|
||||
"@img/sharp-win32-ia32": "0.34.5",
|
||||
"@img/sharp-win32-x64": "0.34.5"
|
||||
"@img/sharp-darwin-arm64": "0.35.0-rc.0",
|
||||
"@img/sharp-darwin-x64": "0.35.0-rc.0",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-arm": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linux-x64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.2",
|
||||
"@img/sharp-linux-arm": "0.35.0-rc.0",
|
||||
"@img/sharp-linux-arm64": "0.35.0-rc.0",
|
||||
"@img/sharp-linux-ppc64": "0.35.0-rc.0",
|
||||
"@img/sharp-linux-riscv64": "0.35.0-rc.0",
|
||||
"@img/sharp-linux-s390x": "0.35.0-rc.0",
|
||||
"@img/sharp-linux-x64": "0.35.0-rc.0",
|
||||
"@img/sharp-linuxmusl-arm64": "0.35.0-rc.0",
|
||||
"@img/sharp-linuxmusl-x64": "0.35.0-rc.0",
|
||||
"@img/sharp-wasm32": "0.35.0-rc.0",
|
||||
"@img/sharp-win32-arm64": "0.35.0-rc.0",
|
||||
"@img/sharp-win32-ia32": "0.35.0-rc.0",
|
||||
"@img/sharp-win32-x64": "0.35.0-rc.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.3.10",
|
||||
"@cpplint/cli": "^0.1.0",
|
||||
"@emnapi/runtime": "^1.7.1",
|
||||
"@img/sharp-libvips-dev": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-dev-wasm32": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-win32-arm64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-win32-ia32": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-win32-x64": "1.3.0-rc.1",
|
||||
"@img/sharp-libvips-dev": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-dev-wasm32": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-win32-arm64": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-win32-ia32": "1.3.0-rc.2",
|
||||
"@img/sharp-libvips-win32-x64": "1.3.0-rc.2",
|
||||
"@types/node": "*",
|
||||
"emnapi": "^1.7.1",
|
||||
"exif-reader": "^2.0.3",
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace sharp {
|
||||
/*
|
||||
Trim an image
|
||||
*/
|
||||
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt) {
|
||||
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt, int const margin) {
|
||||
if (image.width() < 3 && image.height() < 3) {
|
||||
throw VError("Image to trim must be at least 3x3 pixels");
|
||||
}
|
||||
@@ -320,18 +320,36 @@ namespace sharp {
|
||||
if (widthA > 0 && heightA > 0) {
|
||||
if (width > 0 && height > 0) {
|
||||
// Combined bounding box (B)
|
||||
int const leftB = std::min(left, leftA);
|
||||
int const topB = std::min(top, topA);
|
||||
int const widthB = std::max(left + width, leftA + widthA) - leftB;
|
||||
int const heightB = std::max(top + height, topA + heightA) - topB;
|
||||
int leftB = std::min(left, leftA);
|
||||
int topB = std::min(top, topA);
|
||||
int widthB = std::max(left + width, leftA + widthA) - leftB;
|
||||
int heightB = std::max(top + height, topA + heightA) - topB;
|
||||
if (margin > 0) {
|
||||
leftB = std::max(0, leftB - margin);
|
||||
topB = std::max(0, topB - margin);
|
||||
widthB = std::min(image.width() - leftB, widthB + 2 * margin);
|
||||
heightB = std::min(image.height() - topB, heightB + 2 * margin);
|
||||
}
|
||||
return image.extract_area(leftB, topB, widthB, heightB);
|
||||
} else {
|
||||
// Use alpha only
|
||||
if (margin > 0) {
|
||||
leftA = std::max(0, leftA - margin);
|
||||
topA = std::max(0, topA - margin);
|
||||
widthA = std::min(image.width() - leftA, widthA + 2 * margin);
|
||||
heightA = std::min(image.height() - topA, heightA + 2 * margin);
|
||||
}
|
||||
return image.extract_area(leftA, topA, widthA, heightA);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
if (margin > 0) {
|
||||
left = std::max(0, left - margin);
|
||||
top = std::max(0, top - margin);
|
||||
width = std::min(image.width() - left, width + 2 * margin);
|
||||
height = std::min(image.height() - top, height + 2 * margin);
|
||||
}
|
||||
return image.extract_area(left, top, width, height);
|
||||
}
|
||||
return image;
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace sharp {
|
||||
/*
|
||||
Trim an image
|
||||
*/
|
||||
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt);
|
||||
VImage Trim(VImage image, std::vector<double> background, double threshold, bool const lineArt, int const margin);
|
||||
|
||||
/*
|
||||
* Linear adjustment (a * in + b)
|
||||
|
||||
@@ -153,7 +153,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
if (baton->trimThreshold >= 0.0) {
|
||||
MultiPageUnsupported(nPages, "Trim");
|
||||
image = sharp::StaySequential(image);
|
||||
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt);
|
||||
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt, baton->trimMargin);
|
||||
baton->trimOffsetLeft = image.xoffset();
|
||||
baton->trimOffsetTop = image.yoffset();
|
||||
}
|
||||
@@ -1637,6 +1637,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground");
|
||||
baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
|
||||
baton->trimLineArt = sharp::AttrAsBool(options, "trimLineArt");
|
||||
baton->trimMargin = sharp::AttrAsUint32(options, "trimMargin");
|
||||
baton->gamma = sharp::AttrAsDouble(options, "gamma");
|
||||
baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
|
||||
baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA");
|
||||
|
||||
@@ -102,6 +102,7 @@ struct PipelineBaton {
|
||||
bool trimLineArt;
|
||||
int trimOffsetLeft;
|
||||
int trimOffsetTop;
|
||||
int trimMargin;
|
||||
std::vector<double> linearA;
|
||||
std::vector<double> linearB;
|
||||
int dilateWidth;
|
||||
@@ -286,6 +287,7 @@ struct PipelineBaton {
|
||||
trimLineArt(false),
|
||||
trimOffsetLeft(0),
|
||||
trimOffsetTop(0),
|
||||
trimMargin(0),
|
||||
linearA{},
|
||||
linearB{},
|
||||
dilateWidth(0),
|
||||
|
||||
@@ -123,6 +123,7 @@ Napi::Value format(const Napi::CallbackInfo& info) {
|
||||
"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz",
|
||||
"ppm", "fits", "gif", "svg", "heif", "pdf", "vips", "jp2k", "jxl", "rad", "dcraw"
|
||||
}) {
|
||||
std::string id = f == "jp2k" ? "jp2" : f;
|
||||
// Input
|
||||
const VipsObjectClass *oc = vips_class_find("VipsOperation", (f + "load").c_str());
|
||||
Napi::Boolean hasInputFile = Napi::Boolean::New(env, oc);
|
||||
@@ -154,11 +155,11 @@ Napi::Value format(const Napi::CallbackInfo& info) {
|
||||
output.Set("stream", hasOutputBuffer);
|
||||
// Other attributes
|
||||
Napi::Object container = Napi::Object::New(env);
|
||||
container.Set("id", f);
|
||||
container.Set("id", id);
|
||||
container.Set("input", input);
|
||||
container.Set("output", output);
|
||||
// Add to set of formats
|
||||
format.Set(f, container);
|
||||
format.Set(id, container);
|
||||
}
|
||||
|
||||
// Raw, uncompressed data
|
||||
|
||||
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@@ -74,6 +74,7 @@ module.exports = {
|
||||
|
||||
inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
|
||||
inputPngGradients: getPath('gradients-rgb8.png'),
|
||||
inputPngWithSlightGradientBorder: getPath('slight-gradient-border.png'),
|
||||
inputPngWithTransparency: getPath('blackbug.png'), // public domain
|
||||
inputPngCompleteTransparency: getPath('full-transparent.png'),
|
||||
inputPngWithGreyAlpha: getPath('grey-8bit-alpha.png'),
|
||||
|
||||
BIN
test/fixtures/slight-gradient-border.png
vendored
Normal file
BIN
test/fixtures/slight-gradient-border.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -234,7 +234,7 @@ sharp(input)
|
||||
|
||||
sharp(input)
|
||||
.resize(100, 100)
|
||||
.toFormat('jpg')
|
||||
.toFormat('avif')
|
||||
.toBuffer({ resolveWithObject: false })
|
||||
.then((outputBuffer: Buffer) => {
|
||||
// Resolves with a Buffer object when resolveWithObject is false
|
||||
@@ -267,9 +267,7 @@ sharp(input)
|
||||
// Output to tif
|
||||
sharp(input)
|
||||
.resize(100, 100)
|
||||
.toFormat('tif')
|
||||
.toFormat('tiff')
|
||||
.toFormat(sharp.format.tif)
|
||||
.toFormat(sharp.format.tiff)
|
||||
.toBuffer();
|
||||
|
||||
@@ -601,7 +599,7 @@ const vertexSplitQuadraticBasisSpline: string = sharp.interpolators.vertexSplitQ
|
||||
// Triming
|
||||
sharp(input).trim({ background: '#000' }).toBuffer();
|
||||
sharp(input).trim({ threshold: 10, lineArt: true }).toBuffer();
|
||||
sharp(input).trim({ background: '#bf1942', threshold: 30 }).toBuffer();
|
||||
sharp(input).trim({ background: '#bf1942', threshold: 30, margin: 20 }).toBuffer();
|
||||
|
||||
// Text input
|
||||
sharp({
|
||||
@@ -774,3 +772,35 @@ sharp().erode();
|
||||
sharp().erode(1);
|
||||
sharp().dilate();
|
||||
sharp().dilate(1);
|
||||
|
||||
sharp.format.dcraw;
|
||||
sharp.format.dz;
|
||||
sharp.format.fits;
|
||||
sharp.format.gif;
|
||||
sharp.format.heif;
|
||||
sharp.format.jp2;
|
||||
sharp.format.jpeg;
|
||||
sharp.format.jxl;
|
||||
sharp.format.magick;
|
||||
sharp.format.openslide;
|
||||
sharp.format.pdf;
|
||||
sharp.format.png;
|
||||
sharp.format.ppm;
|
||||
sharp.format.rad;
|
||||
sharp.format.raw;
|
||||
sharp.format.svg;
|
||||
sharp.format.tiff;
|
||||
sharp.format.vips;
|
||||
sharp.format.webp;
|
||||
// @ts-expect-error
|
||||
sharp.format.avif;
|
||||
// @ts-expect-error
|
||||
sharp.format.input;
|
||||
// @ts-expect-error
|
||||
sharp.format.jp2k;
|
||||
// @ts-expect-error
|
||||
sharp.format.jpg;
|
||||
// @ts-expect-error
|
||||
sharp.format.tif;
|
||||
// @ts-expect-error
|
||||
sharp.format.v;
|
||||
|
||||
@@ -11,7 +11,7 @@ const sharp = require('../../');
|
||||
const fixtures = require('../fixtures');
|
||||
|
||||
describe('JP2 output', () => {
|
||||
if (!sharp.format.jp2k.input.buffer) {
|
||||
if (!sharp.format.jp2.input.buffer) {
|
||||
it('JP2 output should fail due to missing OpenJPEG', () =>
|
||||
assert.rejects(async () =>
|
||||
sharp(fixtures.inputJpg)
|
||||
|
||||
@@ -180,7 +180,7 @@ describe('libvips binaries', () => {
|
||||
process.env.npm_config_arch = 's390x';
|
||||
process.env.npm_config_libc = '';
|
||||
const locatorHash = libvips.yarnLocator();
|
||||
assert.strictEqual(locatorHash, '8cdba194cb');
|
||||
assert.strictEqual(locatorHash, 'f7e557e9d6');
|
||||
delete process.env.npm_config_platform;
|
||||
delete process.env.npm_config_arch;
|
||||
delete process.env.npm_config_libc;
|
||||
|
||||
@@ -222,6 +222,9 @@ describe('Trim borders', () => {
|
||||
},
|
||||
'Invalid lineArt': {
|
||||
lineArt: 'fail'
|
||||
},
|
||||
'Invalid margin': {
|
||||
margin: -1
|
||||
}
|
||||
}).forEach(([description, parameter]) => {
|
||||
it(description, () => {
|
||||
@@ -289,4 +292,42 @@ describe('Trim borders', () => {
|
||||
assert.strictEqual(trimOffsetLeft, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adds margin around content', () => {
|
||||
it('Should trim complex gradients', async () => {
|
||||
const { info } = await sharp(fixtures.inputPngGradients)
|
||||
.trim({ threshold: 50, margin: 100 })
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
|
||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||
assert.strictEqual(width, 1000);
|
||||
assert.strictEqual(height, 443);
|
||||
assert.strictEqual(trimOffsetTop, -557);
|
||||
assert.strictEqual(trimOffsetLeft, 0);
|
||||
});
|
||||
|
||||
it('Should trim simple gradients', async () => {
|
||||
const { info } = await sharp(fixtures.inputPngWithSlightGradientBorder)
|
||||
.trim({ threshold: 70, margin: 50 })
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
|
||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||
assert.strictEqual(width, 900);
|
||||
assert.strictEqual(height, 900);
|
||||
assert.strictEqual(trimOffsetTop, -50);
|
||||
assert.strictEqual(trimOffsetLeft, -50);
|
||||
});
|
||||
|
||||
it('Should not overflow image bounding box', async () => {
|
||||
const { info } = await sharp(fixtures.inputPngWithSlightGradientBorder)
|
||||
.trim({ threshold: 70, margin: 9999999 })
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
|
||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||
assert.strictEqual(width, 1000);
|
||||
assert.strictEqual(height, 1000);
|
||||
assert.strictEqual(trimOffsetTop, 0);
|
||||
assert.strictEqual(trimOffsetLeft, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user