diff --git a/docs/api-output.md b/docs/api-output.md index 2fb914f1a..a67cf16bd 100644 --- a/docs/api-output.md +++ b/docs/api-output.md @@ -222,6 +222,9 @@ Use these WebP options for output image. - `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.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`) ### Examples @@ -233,6 +236,27 @@ const data = await sharp(input) .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 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.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.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.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'`) @@ -383,4 +407,8 @@ Returns **Sharp** [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 diff --git a/docs/changelog.md b/docs/changelog.md index 0e6008eb6..3e9404f72 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -15,6 +15,10 @@ Requires libvips v8.10.0 * Add most `dominant` colour to image `stats`. [#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. [#2258](https://github.com/lovell/sharp/pull/2258) [@vouillon](https://github.com/vouillon) diff --git a/docs/humans.txt b/docs/humans.txt index 4b47d16c1..f9d394275 100644 --- a/docs/humans.txt +++ b/docs/humans.txt @@ -191,3 +191,6 @@ GitHub: https://github.com/romaleev Name: Jerome Vouillon GitHub: https://github.com/vouillon + +Name: Tomáš Szabo +GitHub: https://github.com/deftomat diff --git a/docs/search-index.json b/docs/search-index.json index 3c9dd339a..44678a159 100644 --- a/docs/search-index.json +++ b/docs/search-index.json @@ -1 +1 @@ -[{"t":"Prerequisites","d":"Node.js v10.16.0","k":"prerequisites node","l":"/install#prerequisites"},{"t":"Prebuilt binaries","d":"Ready-compiled sharp and libvips binaries are provided for use with Node.js v10.16.0 on the most common platforms macOS x64 10.13 Linux x64","k":"prebuilt binaries ready compiled sharp libvips binaries provided node most common platforms macos linux","l":"/install#prebuilt-binaries"},{"t":"Common problems","d":"The architecture and platform of Node.js used for npm install must be the same as the architecture and platform of Node.js used at runtime.","k":"common problems architecture platform node used npm install must same architecture platform node used runtime","l":"/install#common-problems"},{"t":"Custom libvips","d":"To use a custom, globally-installed version of libvips instead of the provided binaries, make sure it is at least the version listed under c","k":"custom libvips custom globally installed version libvips instead provided binaries make sure least version listed under","l":"/install#custom-libvips"},{"t":"Building from source","d":"This module will be compiled from source at npm install time when a globally-installed libvips is detected set the SHARP_IGNORE_GLOBAL_LIBVI","k":"building source module compiled source npm install time globally installed libvips detected sharpignoregloballibvi","l":"/install#building-from-source"},{"t":"Custom prebuilt binaries","d":"This is an advanced approach that most people will not require. To install the prebuilt sharp binaries from a custom URL, set the sharp_bina","k":"custom prebuilt binaries advanced approach most people require install prebuilt sharp binaries custom url sharpbina","l":"/install#custom-prebuilt-binaries"},{"t":"Chinese mirror","d":"Alibaba provide a mirror site based in China containing binaries for both sharp and libvips. To use this either set the following configurat","k":"chinese mirror alibaba provide mirror site based china containing binaries both sharp libvips following configurat","l":"/install#chinese-mirror"},{"t":"FreeBSD","d":"The vips package must be installed before npm install is run. sh pkg install -y pkgconf vips sh cd /usr/ports/graphics/vips/ make install cl","k":"freebsd vips package must installed before npm install run pkg install pkgconf vips usr ports graphics vips make install","l":"/install#freebsd"},{"t":"Heroku","d":"Add the jemalloc buildpack to reduce the effects of memory fragmentation. Set NODE_MODULES_CACHE","k":"heroku add jemalloc buildpack reduce effects memory fragmentation nodemodulescache","l":"/install#heroku"},{"t":"AWS Lambda","d":"Set the Lambda runtime to nodejs12.x. The binaries in the node_modules directory of the deployment package must be for the Linux x64 platfor","k":"aws lambda lambda runtime nodejs binaries nodemodules directory deployment package must linux platfor","l":"/install#aws-lambda"},{"t":"Electron","d":"Electron provides versions of the V8 JavaScript engine that are incompatible with Node.js. To ensure the correct binaries are used, run the","k":"electron electron provides versions javascript engine incompatible node ensure correct binaries used run","l":"/install#electron"},{"t":"Worker threads","d":"The main thread must call requiresharp before worker threads are created to ensure shared libraries remain loaded in memory until after all","k":"worker threads main thread must call requiresharp before worker threads created ensure shared libraries remain loaded memory until after","l":"/install#worker-threads"},{"t":"Sharp","d":"Constructor factory to create an instance of sharp, to which further methods are chained.","k":"sharp constructor factory create instance sharp further methods chained","l":"/api-constructor#sharp"},{"t":"clone","d":"Take a snapshot of the Sharp instance, returning a new instance. Cloned instances inherit the input of their parent instance. This allows mu","k":"clone take snapshot sharp instance returning new instance cloned instances inherit input parent instance allows","l":"/api-constructor#clone"},{"t":"metadata","d":"Fast access to uncached image metadata without decoding any compressed image data. A Promise is returned when callback is not provided.","k":"metadata fast access uncached image metadata without decoding compressed image data promise returned callback provided","l":"/api-input#metadata"},{"t":"stats","d":"Access to pixel-derived image statistics for every channel in the image. A Promise is returned when callback is not provided.","k":"stats access pixel derived image statistics every channel image promise returned callback provided","l":"/api-input#stats"},{"t":"toFile","d":"Write output image data to a file.","k":"tofile write output image data file","l":"/api-output#tofile"},{"t":"toBuffer","d":"Write output to a Buffer. JPEG, PNG, WebP, TIFF and RAW output are supported.","k":"tobuffer write output buffer jpeg png webp tiff raw output supported","l":"/api-output#tobuffer"},{"t":"withMetadata","d":"Include all metadata EXIF, XMP, IPTC from the input image in the output image. This will also convert to and add a web-friendly sRGB ICC pro","k":"withmetadata include metadata exif xmp iptc input image output image also convert add web friendly srgb icc pro","l":"/api-output#withmetadata"},{"t":"toFormat","d":"Force output to a given format.","k":"toformat force output given format","l":"/api-output#toformat"},{"t":"jpeg","d":"Use these JPEG options for output image.","k":"jpeg jpeg options output image","l":"/api-output#jpeg"},{"t":"png","d":"Use these PNG options for output image.","k":"png png options output image","l":"/api-output#png"},{"t":"webp","d":"Use these WebP options for output image.","k":"webp webp options output image","l":"/api-output#webp"},{"t":"tiff","d":"Use these TIFF options for output image.","k":"tiff tiff options output image","l":"/api-output#tiff"},{"t":"heif","d":"Use these HEIF options for output image.","k":"heif heif options output image","l":"/api-output#heif"},{"t":"raw","d":"Force output to be raw, uncompressed, 8-bit unsigned integer unit8 pixel data. Pixel ordering is left-to-right, top-to-bottom, without paddi","k":"raw force output raw uncompressed bit unsigned integer unit pixel data pixel ordering left right top bottom without paddi","l":"/api-output#raw"},{"t":"tile","d":"Use tile-based deep zoom image pyramid output. Set the format and options for tile images via the toFormat, jpeg, png or webp functions. Use","k":"tile tile based deep zoom image pyramid output format options tile images via toformat jpeg png webp functions","l":"/api-output#tile"},{"t":"resize","d":"Resize image to width, height or width x height.","k":"resize resize image width height width height","l":"/api-resize#resize"},{"t":"extend","d":"Extends/pads the edges of the image with the provided background colour. This operation will always occur after resizing and extraction, if","k":"extend extends pads edges image provided background colour operation occur after resizing extraction","l":"/api-resize#extend"},{"t":"extract","d":"Extract/crop a region of the image.","k":"extract extract crop region image","l":"/api-resize#extract"},{"t":"trim","d":"Trim boring pixels from all edges that contain values similar to the top-left pixel. Images consisting entirely of a single colour will calc","k":"trim trim boring pixels edges contain values similar top left pixel images consisting entirely single colour calc","l":"/api-resize#trim"},{"t":"composite","d":"Composite images over the processed resized, extracted etc. image.","k":"composite composite images processed resized extracted image","l":"/api-composite#composite"},{"t":"rotate","d":"Rotate the output image by either an explicit angle or auto-orient based on the EXIF Orientation tag.","k":"rotate rotate output image explicit angle auto orient based exif orientation tag","l":"/api-operation#rotate"},{"t":"flip","d":"Flip the image about the vertical Y axis. This always occurs after rotation, if any. The use of flip implies the removal of the EXIF Orienta","k":"flip flip image vertical axis occurs after rotation flip implies removal exif orienta","l":"/api-operation#flip"},{"t":"flop","d":"Flop the image about the horizontal X axis. This always occurs after rotation, if any. The use of flop implies the removal of the EXIF Orien","k":"flop flop image horizontal axis occurs after rotation flop implies removal exif orien","l":"/api-operation#flop"},{"t":"sharpen","d":"Sharpen the image. When used without parameters, performs a fast, mild sharpen of the output image. When a sigma is provided, performs a slo","k":"sharpen sharpen image used without parameters performs fast mild sharpen output image sigma provided performs slo","l":"/api-operation#sharpen"},{"t":"median","d":"Apply median filter. When used without parameters the default window is 3x3.","k":"median apply median filter used without parameters default window","l":"/api-operation#median"},{"t":"blur","d":"Blur the image. When used without parameters, performs a fast, mild blur of the output image. When a sigma is provided, performs a slower, m","k":"blur blur image used without parameters performs fast mild blur output image sigma provided performs slower","l":"/api-operation#blur"},{"t":"flatten","d":"Merge alpha transparency channel, if any, with a background.","k":"flatten merge alpha transparency channel background","l":"/api-operation#flatten"},{"t":"gamma","d":"Apply a gamma correction by reducing the encoding darken pre-resize at a factor of 1/gamma then increasing the encoding brighten post-resize","k":"gamma apply gamma correction reducing encoding darken pre resize factor gamma then increasing encoding brighten post resize","l":"/api-operation#gamma"},{"t":"negate","d":"Produce the negative of the image.","k":"negate produce negative image","l":"/api-operation#negate"},{"t":"normalise","d":"Enhance output image contrast by stretching its luminance to cover the full dynamic range.","k":"normalise enhance output image contrast stretching luminance cover full dynamic range","l":"/api-operation#normalise"},{"t":"normalize","d":"Alternative spelling of normalise.","k":"normalize alternative spelling normalise","l":"/api-operation#normalize"},{"t":"convolve","d":"Convolve the image with the specified kernel.","k":"convolve convolve image specified kernel","l":"/api-operation#convolve"},{"t":"threshold","d":"Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0.","k":"threshold pixel value greather than equal threshold value otherwise","l":"/api-operation#threshold"},{"t":"boolean","d":"Perform a bitwise boolean operation with operand image.","k":"boolean perform bitwise boolean operation operand image","l":"/api-operation#boolean"},{"t":"linear","d":"Apply the linear formula a input b to the image levels adjustment","k":"linear apply linear formula input image levels adjustment","l":"/api-operation#linear"},{"t":"recomb","d":"Recomb the image with the specified matrix.","k":"recomb recomb image specified matrix","l":"/api-operation#recomb"},{"t":"modulate","d":"Transforms the image using brightness, saturation and hue rotation.","k":"modulate transforms image brightness saturation hue rotation","l":"/api-operation#modulate"},{"t":"removeAlpha","d":"Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.","k":"removealpha remove alpha channel image alpha channel","l":"/api-channel#removealpha"},{"t":"ensureAlpha","d":"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.","k":"ensurealpha ensure alpha channel missing added alpha channel fully opaque image alpha channel","l":"/api-channel#ensurealpha"},{"t":"extractChannel","d":"Extract a single channel from a multi-channel image.","k":"extractchannel extract single channel multi channel image","l":"/api-channel#extractchannel"},{"t":"joinChannel","d":"Join one or more channels to the image. The meaning of the added channels depends on the output colourspace, set with toColourspace. By defa","k":"joinchannel join one channels image meaning added channels depends output colourspace tocolourspace defa","l":"/api-channel#joinchannel"},{"t":"bandbool","d":"Perform a bitwise boolean operation on all input image channels bands to produce a single channel output image.","k":"bandbool perform bitwise boolean operation input image channels bands produce single channel output image","l":"/api-channel#bandbool"},{"t":"tint","d":"Tint the image using the provided chroma while preserving the image luminance. An alpha channel may be present and will be unchanged by the","k":"tint tint image provided chroma while preserving image luminance alpha channel present unchanged","l":"/api-colour#tint"},{"t":"greyscale","d":"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,","k":"greyscale convert bit greyscale shades grey linear operation input image non linear colour space such srgb","l":"/api-colour#greyscale"},{"t":"grayscale","d":"Alternative spelling of greyscale.","k":"grayscale alternative spelling greyscale","l":"/api-colour#grayscale"},{"t":"toColourspace","d":"Set the output colourspace. By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.","k":"tocolourspace output colourspace default output image web friendly srgb additional channels interpreted alpha channels","l":"/api-colour#tocolourspace"},{"t":"toColorspace","d":"Alternative spelling of toColourspace.","k":"tocolorspace alternative spelling tocolourspace","l":"/api-colour#tocolorspace"},{"t":"format","d":"An Object containing nested boolean values representing the available input and output formats/methods.","k":"format object containing nested boolean values representing available input output formats methods","l":"/api-utility#format"},{"t":"versions","d":"An Object containing the version numbers of libvips and its dependencies.","k":"versions object containing version numbers libvips dependencies","l":"/api-utility#versions"},{"t":"cache","d":"Gets or, when options are provided, sets the limits of _libvips_ operation cache. Existing entries in the cache will be trimmed after any ch","k":"cache options provided limits libvips operation cache existing entries cache trimmed after","l":"/api-utility#cache"},{"t":"concurrency","d":"Gets or, when a concurrency is provided, sets the number of threads _libvips_ should create to process each image. The default value is the","k":"concurrency concurrency provided number threads libvips create process image default value","l":"/api-utility#concurrency"},{"t":"queue","d":"An EventEmitter that emits a change event when a task is either","k":"queue eventemitter emits change event task","l":"/api-utility#queue"},{"t":"counters","d":"Provides access to internal task counters.","k":"counters provides access internal task counters","l":"/api-utility#counters"},{"t":"simd","d":"Get and set use of SIMD vector unit instructions. Requires libvips to have been compiled with liborc support.","k":"simd simd vector unit instructions requires libvips compiled liborc support","l":"/api-utility#simd"}] \ No newline at end of file +[{"t":"Prerequisites","d":"Node.js v10.16.0","k":"prerequisites node","l":"/install#prerequisites"},{"t":"Prebuilt binaries","d":"Ready-compiled sharp and libvips binaries are provided for use with Node.js v10.16.0 on the most common platforms macOS x64 10.13 Linux x64","k":"prebuilt binaries ready compiled sharp libvips binaries provided node most common platforms macos linux","l":"/install#prebuilt-binaries"},{"t":"Common problems","d":"The architecture and platform of Node.js used for npm install must be the same as the architecture and platform of Node.js used at runtime.","k":"common problems architecture platform node used npm install must same architecture platform node used runtime","l":"/install#common-problems"},{"t":"Custom libvips","d":"To use a custom, globally-installed version of libvips instead of the provided binaries, make sure it is at least the version listed under c","k":"custom libvips custom globally installed version libvips instead provided binaries make sure least version listed under","l":"/install#custom-libvips"},{"t":"Building from source","d":"This module will be compiled from source at npm install time when a globally-installed libvips is detected set the SHARP_IGNORE_GLOBAL_LIBVI","k":"building source module compiled source npm install time globally installed libvips detected sharpignoregloballibvi","l":"/install#building-from-source"},{"t":"Custom prebuilt binaries","d":"This is an advanced approach that most people will not require. To install the prebuilt sharp binaries from a custom URL, set the sharp_bina","k":"custom prebuilt binaries advanced approach most people require install prebuilt sharp binaries custom url sharpbina","l":"/install#custom-prebuilt-binaries"},{"t":"Chinese mirror","d":"Alibaba provide a mirror site based in China containing binaries for both sharp and libvips. To use this either set the following configurat","k":"chinese mirror alibaba provide mirror site based china containing binaries both sharp libvips following configurat","l":"/install#chinese-mirror"},{"t":"FreeBSD","d":"The vips package must be installed before npm install is run. sh pkg install -y pkgconf vips sh cd /usr/ports/graphics/vips/ make install cl","k":"freebsd vips package must installed before npm install run pkg install pkgconf vips usr ports graphics vips make install","l":"/install#freebsd"},{"t":"Heroku","d":"Add the jemalloc buildpack to reduce the effects of memory fragmentation. Set NODE_MODULES_CACHE","k":"heroku add jemalloc buildpack reduce effects memory fragmentation nodemodulescache","l":"/install#heroku"},{"t":"AWS Lambda","d":"Set the Lambda runtime to nodejs12.x. The binaries in the node_modules directory of the deployment package must be for the Linux x64 platfor","k":"aws lambda lambda runtime nodejs binaries nodemodules directory deployment package must linux platfor","l":"/install#aws-lambda"},{"t":"Electron","d":"Electron provides versions of the V8 JavaScript engine that are incompatible with Node.js. To ensure the correct binaries are used, run the","k":"electron electron provides versions javascript engine incompatible node ensure correct binaries used run","l":"/install#electron"},{"t":"Worker threads","d":"The main thread must call requiresharp before worker threads are created to ensure shared libraries remain loaded in memory until after all","k":"worker threads main thread must call requiresharp before worker threads created ensure shared libraries remain loaded memory until after","l":"/install#worker-threads"},{"t":"Sharp","d":"Constructor factory to create an instance of sharp, to which further methods are chained.","k":"sharp constructor factory create instance sharp further methods chained","l":"/api-constructor#sharp"},{"t":"clone","d":"Take a snapshot of the Sharp instance, returning a new instance. Cloned instances inherit the input of their parent instance. This allows mu","k":"clone take snapshot sharp instance returning new instance cloned instances inherit input parent instance allows","l":"/api-constructor#clone"},{"t":"metadata","d":"Fast access to uncached image metadata without decoding any compressed image data. A Promise is returned when callback is not provided.","k":"metadata fast access uncached image metadata without decoding compressed image data promise returned callback provided","l":"/api-input#metadata"},{"t":"stats","d":"Access to pixel-derived image statistics for every channel in the image. A Promise is returned when callback is not provided.","k":"stats access pixel derived image statistics every channel image promise returned callback provided","l":"/api-input#stats"},{"t":"toFile","d":"Write output image data to a file.","k":"tofile write output image data file","l":"/api-output#tofile"},{"t":"toBuffer","d":"Write output to a Buffer. JPEG, PNG, WebP, TIFF and RAW output are supported.","k":"tobuffer write output buffer jpeg png webp tiff raw output supported","l":"/api-output#tobuffer"},{"t":"withMetadata","d":"Include all metadata EXIF, XMP, IPTC from the input image in the output image. This will also convert to and add a web-friendly sRGB ICC pro","k":"withmetadata include metadata exif xmp iptc input image output image also convert add web friendly srgb icc pro","l":"/api-output#withmetadata"},{"t":"toFormat","d":"Force output to a given format.","k":"toformat force output given format","l":"/api-output#toformat"},{"t":"jpeg","d":"Use these JPEG options for output image.","k":"jpeg jpeg options output image","l":"/api-output#jpeg"},{"t":"png","d":"Use these PNG options for output image.","k":"png png options output image","l":"/api-output#png"},{"t":"webp","d":"Use these WebP options for output image.","k":"webp webp options output image","l":"/api-output#webp"},{"t":"gif","d":"Use these GIF options for output image.","k":"gif gif options output image","l":"/api-output#gif"},{"t":"tiff","d":"Use these TIFF options for output image.","k":"tiff tiff options output image","l":"/api-output#tiff"},{"t":"heif","d":"Use these HEIF options for output image.","k":"heif heif options output image","l":"/api-output#heif"},{"t":"raw","d":"Force output to be raw, uncompressed, 8-bit unsigned integer unit8 pixel data. Pixel ordering is left-to-right, top-to-bottom, without paddi","k":"raw force output raw uncompressed bit unsigned integer unit pixel data pixel ordering left right top bottom without paddi","l":"/api-output#raw"},{"t":"tile","d":"Use tile-based deep zoom image pyramid output. Set the format and options for tile images via the toFormat, jpeg, png or webp functions. Use","k":"tile tile based deep zoom image pyramid output format options tile images via toformat jpeg png webp functions","l":"/api-output#tile"},{"t":"resize","d":"Resize image to width, height or width x height.","k":"resize resize image width height width height","l":"/api-resize#resize"},{"t":"extend","d":"Extends/pads the edges of the image with the provided background colour. This operation will always occur after resizing and extraction, if","k":"extend extends pads edges image provided background colour operation occur after resizing extraction","l":"/api-resize#extend"},{"t":"extract","d":"Extract/crop a region of the image.","k":"extract extract crop region image","l":"/api-resize#extract"},{"t":"trim","d":"Trim boring pixels from all edges that contain values similar to the top-left pixel. Images consisting entirely of a single colour will calc","k":"trim trim boring pixels edges contain values similar top left pixel images consisting entirely single colour calc","l":"/api-resize#trim"},{"t":"composite","d":"Composite images over the processed resized, extracted etc. image.","k":"composite composite images processed resized extracted image","l":"/api-composite#composite"},{"t":"rotate","d":"Rotate the output image by either an explicit angle or auto-orient based on the EXIF Orientation tag.","k":"rotate rotate output image explicit angle auto orient based exif orientation tag","l":"/api-operation#rotate"},{"t":"flip","d":"Flip the image about the vertical Y axis. This always occurs after rotation, if any. The use of flip implies the removal of the EXIF Orienta","k":"flip flip image vertical axis occurs after rotation flip implies removal exif orienta","l":"/api-operation#flip"},{"t":"flop","d":"Flop the image about the horizontal X axis. This always occurs after rotation, if any. The use of flop implies the removal of the EXIF Orien","k":"flop flop image horizontal axis occurs after rotation flop implies removal exif orien","l":"/api-operation#flop"},{"t":"sharpen","d":"Sharpen the image. When used without parameters, performs a fast, mild sharpen of the output image. When a sigma is provided, performs a slo","k":"sharpen sharpen image used without parameters performs fast mild sharpen output image sigma provided performs slo","l":"/api-operation#sharpen"},{"t":"median","d":"Apply median filter. When used without parameters the default window is 3x3.","k":"median apply median filter used without parameters default window","l":"/api-operation#median"},{"t":"blur","d":"Blur the image. When used without parameters, performs a fast, mild blur of the output image. When a sigma is provided, performs a slower, m","k":"blur blur image used without parameters performs fast mild blur output image sigma provided performs slower","l":"/api-operation#blur"},{"t":"flatten","d":"Merge alpha transparency channel, if any, with a background.","k":"flatten merge alpha transparency channel background","l":"/api-operation#flatten"},{"t":"gamma","d":"Apply a gamma correction by reducing the encoding darken pre-resize at a factor of 1/gamma then increasing the encoding brighten post-resize","k":"gamma apply gamma correction reducing encoding darken pre resize factor gamma then increasing encoding brighten post resize","l":"/api-operation#gamma"},{"t":"negate","d":"Produce the negative of the image.","k":"negate produce negative image","l":"/api-operation#negate"},{"t":"normalise","d":"Enhance output image contrast by stretching its luminance to cover the full dynamic range.","k":"normalise enhance output image contrast stretching luminance cover full dynamic range","l":"/api-operation#normalise"},{"t":"normalize","d":"Alternative spelling of normalise.","k":"normalize alternative spelling normalise","l":"/api-operation#normalize"},{"t":"convolve","d":"Convolve the image with the specified kernel.","k":"convolve convolve image specified kernel","l":"/api-operation#convolve"},{"t":"threshold","d":"Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0.","k":"threshold pixel value greather than equal threshold value otherwise","l":"/api-operation#threshold"},{"t":"boolean","d":"Perform a bitwise boolean operation with operand image.","k":"boolean perform bitwise boolean operation operand image","l":"/api-operation#boolean"},{"t":"linear","d":"Apply the linear formula a input b to the image levels adjustment","k":"linear apply linear formula input image levels adjustment","l":"/api-operation#linear"},{"t":"recomb","d":"Recomb the image with the specified matrix.","k":"recomb recomb image specified matrix","l":"/api-operation#recomb"},{"t":"modulate","d":"Transforms the image using brightness, saturation and hue rotation.","k":"modulate transforms image brightness saturation hue rotation","l":"/api-operation#modulate"},{"t":"removeAlpha","d":"Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.","k":"removealpha remove alpha channel image alpha channel","l":"/api-channel#removealpha"},{"t":"ensureAlpha","d":"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.","k":"ensurealpha ensure alpha channel missing added alpha channel fully opaque image alpha channel","l":"/api-channel#ensurealpha"},{"t":"extractChannel","d":"Extract a single channel from a multi-channel image.","k":"extractchannel extract single channel multi channel image","l":"/api-channel#extractchannel"},{"t":"joinChannel","d":"Join one or more channels to the image. The meaning of the added channels depends on the output colourspace, set with toColourspace. By defa","k":"joinchannel join one channels image meaning added channels depends output colourspace tocolourspace defa","l":"/api-channel#joinchannel"},{"t":"bandbool","d":"Perform a bitwise boolean operation on all input image channels bands to produce a single channel output image.","k":"bandbool perform bitwise boolean operation input image channels bands produce single channel output image","l":"/api-channel#bandbool"},{"t":"tint","d":"Tint the image using the provided chroma while preserving the image luminance. An alpha channel may be present and will be unchanged by the","k":"tint tint image provided chroma while preserving image luminance alpha channel present unchanged","l":"/api-colour#tint"},{"t":"greyscale","d":"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,","k":"greyscale convert bit greyscale shades grey linear operation input image non linear colour space such srgb","l":"/api-colour#greyscale"},{"t":"grayscale","d":"Alternative spelling of greyscale.","k":"grayscale alternative spelling greyscale","l":"/api-colour#grayscale"},{"t":"toColourspace","d":"Set the output colourspace. By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.","k":"tocolourspace output colourspace default output image web friendly srgb additional channels interpreted alpha channels","l":"/api-colour#tocolourspace"},{"t":"toColorspace","d":"Alternative spelling of toColourspace.","k":"tocolorspace alternative spelling tocolourspace","l":"/api-colour#tocolorspace"},{"t":"format","d":"An Object containing nested boolean values representing the available input and output formats/methods.","k":"format object containing nested boolean values representing available input output formats methods","l":"/api-utility#format"},{"t":"versions","d":"An Object containing the version numbers of libvips and its dependencies.","k":"versions object containing version numbers libvips dependencies","l":"/api-utility#versions"},{"t":"cache","d":"Gets or, when options are provided, sets the limits of _libvips_ operation cache. Existing entries in the cache will be trimmed after any ch","k":"cache options provided limits libvips operation cache existing entries cache trimmed after","l":"/api-utility#cache"},{"t":"concurrency","d":"Gets or, when a concurrency is provided, sets the number of threads _libvips_ should create to process each image. The default value is the","k":"concurrency concurrency provided number threads libvips create process image default value","l":"/api-utility#concurrency"},{"t":"queue","d":"An EventEmitter that emits a change event when a task is either","k":"queue eventemitter emits change event task","l":"/api-utility#queue"},{"t":"counters","d":"Provides access to internal task counters.","k":"counters provides access internal task counters","l":"/api-utility#counters"},{"t":"simd","d":"Get and set use of SIMD vector unit instructions. Requires libvips to have been compiled with liborc support.","k":"simd simd vector unit instructions requires libvips compiled liborc support","l":"/api-utility#simd"}] \ No newline at end of file diff --git a/lib/output.js b/lib/output.js index 27594db03..737a684bc 100644 --- a/lib/output.js +++ b/lib/output.js @@ -387,7 +387,9 @@ function webp (options) { /** * 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 {number} [options.pageHeight] - page height for animated output @@ -398,12 +400,16 @@ function webp (options) { * @throws {Error} Invalid 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); return this._updateFormatOut('gif', options); } /** * Set animation options if available. + * @private * * @param {Object} [source] - output options * @param {number} [source.pageHeight] - page height for animated output diff --git a/src/common.cc b/src/common.cc index 1bd5b6be8..612dd7efd 100644 --- a/src/common.cc +++ b/src/common.cc @@ -485,16 +485,18 @@ namespace sharp { Check the proposed format supports the current dimensions. */ 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 (image.width() > 65535 || image.height() > 65535) { + if (image.width() > 65535 || height > 65535) { throw vips::VError("Processed image is too large for the JPEG format"); } } 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"); } } 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) { throw vips::VError("Processed image is too large for the GIF format"); } diff --git a/test/unit/gif.js b/test/unit/gif.js index e26d566f5..eebe33ece 100644 --- a/test/unit/gif.js +++ b/test/unit/gif.js @@ -42,7 +42,7 @@ describe('GIF input', () => { .then(({ data, info }) => { assert.strictEqual(true, data.length > 0); 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.height); assert.strictEqual(4, info.channels); @@ -55,22 +55,22 @@ describe('GIF input', () => { .then(({ data, info }) => { assert.strictEqual(true, data.length > 0); 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(2400, info.height); assert.strictEqual(4, info.channels); }) ); - if (!sharp.format.magick.input.buffer) { - it('Animated GIF output should fail due to missing ImageMagick', () => - assert.rejects(() => - sharp(fixtures.inputGifAnimated, { pages: -1 }) - .gif({ loop: 2, delay: [...Array(10).fill(100)], pageHeight: 10 }) - .toBuffer(), - /VipsOperation: class "magicksave_buffer" not found/ - ) - ); + if (!sharp.format.magick.output.buffer) { + it('GIF output should fail due to missing ImageMagick', () => { + assert.throws( + () => { + sharp().gif(); + }, + /The gif operation requires libvips to have been installed with support for ImageMagick/ + ); + }); } it('invalid pageHeight throws', () => { diff --git a/test/unit/io.js b/test/unit/io.js index c5495be74..41ff62d62 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -470,7 +470,7 @@ describe('Input/output', function () { .toFile(fixtures.outputZoinks, function (err, info) { if (err) throw err; 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(80, info.height); rimraf(fixtures.outputZoinks, done);