Doc refresh and changelog entry for #2012

This commit is contained in:
Lovell Fuller 2020-08-17 16:20:10 +01:00
parent cb1baede87
commit 341ea3e4ea
8 changed files with 62 additions and 19 deletions

View File

@ -222,6 +222,9 @@ Use these WebP options for output image.
- `options.nearLossless` **[boolean][7]** use near_lossless compression mode (optional, default `false`) - `options.nearLossless` **[boolean][7]** use near_lossless compression mode (optional, default `false`)
- `options.smartSubsample` **[boolean][7]** use high quality chroma subsampling (optional, default `false`) - `options.smartSubsample` **[boolean][7]** use high quality chroma subsampling (optional, default `false`)
- `options.reductionEffort` **[number][9]** level of CPU effort to reduce file size, integer 0-6 (optional, default `4`) - `options.reductionEffort` **[number][9]** level of CPU effort to reduce file size, integer 0-6 (optional, default `4`)
- `options.pageHeight` **[number][9]?** page height for animated output
- `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
- `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
- `options.force` **[boolean][7]** force WebP output, otherwise attempt to use input format (optional, default `true`) - `options.force` **[boolean][7]** force WebP output, otherwise attempt to use input format (optional, default `true`)
### Examples ### Examples
@ -233,6 +236,27 @@ const data = await sharp(input)
.toBuffer(); .toBuffer();
``` ```
- Throws **[Error][4]** Invalid options
Returns **Sharp**
## gif
Use these GIF options for output image.
Requires libvips compiled with support for ImageMagick or GraphicsMagick.
The prebuilt binaries do not include this - see
[installing a custom libvips][11].
### Parameters
- `options` **[Object][6]?** output options
- `options.pageHeight` **[number][9]?** page height for animated output
- `options.loop` **[number][9]** number of animation iterations, use 0 for infinite animation (optional, default `0`)
- `options.delay` **[Array][10]<[number][9]>?** list of delays between animation frames (in milliseconds)
- `options.force` **[boolean][7]** force GIF output, otherwise attempt to use input format (optional, default `true`)
- Throws **[Error][4]** Invalid options - Throws **[Error][4]** Invalid options
Returns **Sharp** Returns **Sharp**
@ -341,7 +365,7 @@ Warning: multiple sharp instances concurrently producing tile output can expose
- `options.size` **[number][9]** tile size in pixels, a value between 1 and 8192. (optional, default `256`) - `options.size` **[number][9]** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
- `options.overlap` **[number][9]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`) - `options.overlap` **[number][9]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
- `options.angle` **[number][9]** tile angle of rotation, must be a multiple of 90. (optional, default `0`) - `options.angle` **[number][9]** tile angle of rotation, must be a multiple of 90. (optional, default `0`)
- `options.background` **([string][2] \| [Object][6])** background colour, parsed by the [color][10] module, defaults to white without transparency. (optional, default `{r:255,g:255,b:255,alpha:1}`) - `options.background` **([string][2] \| [Object][6])** background colour, parsed by the [color][12] module, defaults to white without transparency. (optional, default `{r:255,g:255,b:255,alpha:1}`)
- `options.depth` **[string][2]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout. - `options.depth` **[string][2]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
- `options.skipBlanks` **[number][9]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`) - `options.skipBlanks` **[number][9]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`)
- `options.container` **[string][2]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`) - `options.container` **[string][2]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
@ -383,4 +407,8 @@ Returns **Sharp**
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number [9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[10]: https://www.npmjs.org/package/color [10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[11]: https://sharp.pixelplumbing.com/install#custom-libvips
[12]: https://www.npmjs.org/package/color

View File

@ -15,6 +15,10 @@ Requires libvips v8.10.0
* Add most `dominant` colour to image `stats`. * Add most `dominant` colour to image `stats`.
[#640](https://github.com/lovell/sharp/issues/640) [#640](https://github.com/lovell/sharp/issues/640)
* Add support for animated GIF (requires \*magick) and WebP output.
[#2012](https://github.com/lovell/sharp/pull/2012)
[@deftomat](https://github.com/deftomat)
* Add support for libvips ImageMagick v7 loaders. * Add support for libvips ImageMagick v7 loaders.
[#2258](https://github.com/lovell/sharp/pull/2258) [#2258](https://github.com/lovell/sharp/pull/2258)
[@vouillon](https://github.com/vouillon) [@vouillon](https://github.com/vouillon)

View File

@ -191,3 +191,6 @@ GitHub: https://github.com/romaleev
Name: Jerome Vouillon Name: Jerome Vouillon
GitHub: https://github.com/vouillon GitHub: https://github.com/vouillon
Name: Tomáš Szabo
GitHub: https://github.com/deftomat

File diff suppressed because one or more lines are too long

View File

@ -387,7 +387,9 @@ function webp (options) {
/** /**
* Use these GIF options for output image. * Use these GIF options for output image.
* *
* Requires a custom, globally-installed libvips compiled with support for imageMagick. * Requires libvips compiled with support for ImageMagick or GraphicsMagick.
* The prebuilt binaries do not include this - see
* {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
* *
* @param {Object} [options] - output options * @param {Object} [options] - output options
* @param {number} [options.pageHeight] - page height for animated output * @param {number} [options.pageHeight] - page height for animated output
@ -398,12 +400,16 @@ function webp (options) {
* @throws {Error} Invalid options * @throws {Error} Invalid options
*/ */
function gif (options) { function gif (options) {
if (!this.constructor.format.magick.output.buffer) {
throw new Error('The gif operation requires libvips to have been installed with support for ImageMagick');
}
trySetAnimationOptions(options, this.options); trySetAnimationOptions(options, this.options);
return this._updateFormatOut('gif', options); return this._updateFormatOut('gif', options);
} }
/** /**
* Set animation options if available. * Set animation options if available.
* @private
* *
* @param {Object} [source] - output options * @param {Object} [source] - output options
* @param {number} [source.pageHeight] - page height for animated output * @param {number} [source.pageHeight] - page height for animated output

View File

@ -485,16 +485,18 @@ namespace sharp {
Check the proposed format supports the current dimensions. Check the proposed format supports the current dimensions.
*/ */
void AssertImageTypeDimensions(VImage image, ImageType const imageType) { void AssertImageTypeDimensions(VImage image, ImageType const imageType) {
const int height = image.get_typeof("pageHeight") == G_TYPE_INT
? image.get_int("pageHeight")
: image.height();
if (imageType == ImageType::JPEG) { if (imageType == ImageType::JPEG) {
if (image.width() > 65535 || image.height() > 65535) { if (image.width() > 65535 || height > 65535) {
throw vips::VError("Processed image is too large for the JPEG format"); throw vips::VError("Processed image is too large for the JPEG format");
} }
} else if (imageType == ImageType::WEBP) { } else if (imageType == ImageType::WEBP) {
if (image.width() > 16383 || image.height() > 16383) { if (image.width() > 16383 || height > 16383) {
throw vips::VError("Processed image is too large for the WebP format"); throw vips::VError("Processed image is too large for the WebP format");
} }
} else if (imageType == ImageType::GIF) { } else if (imageType == ImageType::GIF) {
const int height = image.get_typeof("pageHeight") == G_TYPE_INT ? image.get_int("pageHeight") : image.height();
if (image.width() > 65535 || height > 65535) { if (image.width() > 65535 || height > 65535) {
throw vips::VError("Processed image is too large for the GIF format"); throw vips::VError("Processed image is too large for the GIF format");
} }

View File

@ -42,7 +42,7 @@ describe('GIF input', () => {
.then(({ data, info }) => { .then(({ data, info }) => {
assert.strictEqual(true, data.length > 0); assert.strictEqual(true, data.length > 0);
assert.strictEqual(data.length, info.size); assert.strictEqual(data.length, info.size);
assert.strictEqual('png', info.format); assert.strictEqual(sharp.format.magick.input.buffer ? 'gif' : 'png', info.format);
assert.strictEqual(80, info.width); assert.strictEqual(80, info.width);
assert.strictEqual(80, info.height); assert.strictEqual(80, info.height);
assert.strictEqual(4, info.channels); assert.strictEqual(4, info.channels);
@ -55,22 +55,22 @@ describe('GIF input', () => {
.then(({ data, info }) => { .then(({ data, info }) => {
assert.strictEqual(true, data.length > 0); assert.strictEqual(true, data.length > 0);
assert.strictEqual(data.length, info.size); assert.strictEqual(data.length, info.size);
assert.strictEqual('png', info.format); assert.strictEqual(sharp.format.magick.input.buffer ? 'gif' : 'png', info.format);
assert.strictEqual(80, info.width); assert.strictEqual(80, info.width);
assert.strictEqual(2400, info.height); assert.strictEqual(2400, info.height);
assert.strictEqual(4, info.channels); assert.strictEqual(4, info.channels);
}) })
); );
if (!sharp.format.magick.input.buffer) { if (!sharp.format.magick.output.buffer) {
it('Animated GIF output should fail due to missing ImageMagick', () => it('GIF output should fail due to missing ImageMagick', () => {
assert.rejects(() => assert.throws(
sharp(fixtures.inputGifAnimated, { pages: -1 }) () => {
.gif({ loop: 2, delay: [...Array(10).fill(100)], pageHeight: 10 }) sharp().gif();
.toBuffer(), },
/VipsOperation: class "magicksave_buffer" not found/ /The gif operation requires libvips to have been installed with support for ImageMagick/
)
); );
});
} }
it('invalid pageHeight throws', () => { it('invalid pageHeight throws', () => {

View File

@ -470,7 +470,7 @@ describe('Input/output', function () {
.toFile(fixtures.outputZoinks, function (err, info) { .toFile(fixtures.outputZoinks, function (err, info) {
if (err) throw err; if (err) throw err;
assert.strictEqual(true, info.size > 0); assert.strictEqual(true, info.size > 0);
assert.strictEqual('png', info.format); assert.strictEqual(sharp.format.magick.input.buffer ? 'gif' : 'png', info.format);
assert.strictEqual(320, info.width); assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height); assert.strictEqual(80, info.height);
rimraf(fixtures.outputZoinks, done); rimraf(fixtures.outputZoinks, done);