mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Upgrade to libvips v8.14.0-rc1
- Replace GIF 'optimise' option with 'reuse' - Add 'progressive' option to GIF - Add 'wrap' option to text creation - Add 'formatMagick' property to *magick input metadata
This commit is contained in:
parent
844deaf480
commit
eac6e8b261
@ -63,6 +63,7 @@ Implements the [stream.Duplex][1] class.
|
||||
* `options.text.dpi` **[number][14]** the resolution (size) at which to render the text. Does not take effect if `height` is specified. (optional, default `72`)
|
||||
* `options.text.rgba` **[boolean][15]** 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>`. (optional, default `false`)
|
||||
* `options.text.spacing` **[number][14]** text line height in points. Will use the font line height if none is specified. (optional, default `0`)
|
||||
* `options.text.wrap` **[number][14]** word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none'. (optional, default `'word'`)
|
||||
|
||||
### Examples
|
||||
|
||||
|
@ -328,8 +328,8 @@ The palette of the input image will be re-used if possible.
|
||||
|
||||
* `options` **[Object][6]?** output options
|
||||
|
||||
* `options.reoptimise` **[boolean][10]** always generate new palettes (slow), re-use existing by default (optional, default `false`)
|
||||
* `options.reoptimize` **[boolean][10]** alternative spelling of `options.reoptimise` (optional, default `false`)
|
||||
* `options.reuse` **[boolean][10]** re-use existing palette, otherwise generate new (slow) (optional, default `true`)
|
||||
* `options.progressive` **[boolean][10]** use progressive (interlace) scan (optional, default `false`)
|
||||
* `options.colours` **[number][12]** maximum number of palette entries, including transparency, between 2 and 256 (optional, default `256`)
|
||||
* `options.colors` **[number][12]** alternative spelling of `options.colours` (optional, default `256`)
|
||||
* `options.effort` **[number][12]** CPU effort, between 1 (fastest) and 10 (slowest) (optional, default `7`)
|
||||
|
@ -1,5 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## v0.32 - *flow*
|
||||
|
||||
Requires libvips v8.14.0
|
||||
|
||||
### v0.32.0 - TBD
|
||||
|
||||
* Replace GIF output `optimise` / `optimize` option with `reuse`.
|
||||
|
||||
* Add `progressive` option to GIF output for interlacing.
|
||||
|
||||
* Add `wrap` option to text image creation.
|
||||
|
||||
* Add `formatMagick` property to metadata of images loaded via *magick.
|
||||
|
||||
* Allow use of GPS (IFD3) EXIF metadata.
|
||||
[#2767](https://github.com/lovell/sharp/issues/2767)
|
||||
|
||||
* Prebuilt binaries: ensure macOS 10.13+ support, as documented.
|
||||
[#3438](https://github.com/lovell/sharp/issues/3438)
|
||||
|
||||
* Prebuilt binaries: prevent use of glib slice allocator, improves QEMU support.
|
||||
[#3448](https://github.com/lovell/sharp/issues/3448)
|
||||
|
||||
## v0.31 - *eagle*
|
||||
|
||||
Requires libvips v8.13.3
|
||||
|
@ -158,6 +158,7 @@ const debuglog = util.debuglog('sharp');
|
||||
* @param {number} [options.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
|
||||
* @param {boolean} [options.text.rgba=false] - 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>`.
|
||||
* @param {number} [options.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
|
||||
* @param {number} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none'.
|
||||
* @returns {Sharp}
|
||||
* @throws {Error} Invalid parameters
|
||||
*/
|
||||
@ -291,7 +292,8 @@ const Sharp = function (input, options) {
|
||||
gifDither: 1,
|
||||
gifInterFrameMaxError: 0,
|
||||
gifInterPaletteMaxError: 3,
|
||||
gifReoptimise: false,
|
||||
gifReuse: true,
|
||||
gifProgressive: false,
|
||||
tiffQuality: 80,
|
||||
tiffCompression: 'jpeg',
|
||||
tiffPredictor: 'horizontal',
|
||||
|
@ -327,6 +327,13 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
throw is.invalidParameterError('text.spacing', 'number', inputOptions.text.spacing);
|
||||
}
|
||||
}
|
||||
if (is.defined(inputOptions.text.wrap)) {
|
||||
if (is.string(inputOptions.text.wrap) && is.inArray(inputOptions.text.wrap, ['word', 'char', 'wordChar', 'none'])) {
|
||||
inputDescriptor.textWrap = inputOptions.text.wrap;
|
||||
} else {
|
||||
throw is.invalidParameterError('text.wrap', 'one of: word, char, wordChar, none', inputOptions.text.wrap);
|
||||
}
|
||||
}
|
||||
delete inputDescriptor.buffer;
|
||||
} else {
|
||||
throw new Error('Expected a valid string to create an image with text.');
|
||||
|
@ -559,8 +559,8 @@ function webp (options) {
|
||||
* .toFile('optim.gif');
|
||||
*
|
||||
* @param {Object} [options] - output options
|
||||
* @param {boolean} [options.reoptimise=false] - always generate new palettes (slow), re-use existing by default
|
||||
* @param {boolean} [options.reoptimize=false] - alternative spelling of `options.reoptimise`
|
||||
* @param {boolean} [options.reuse=true] - re-use existing palette, otherwise generate new (slow)
|
||||
* @param {boolean} [options.progressive=false] - use progressive (interlace) scan
|
||||
* @param {number} [options.colours=256] - maximum number of palette entries, including transparency, between 2 and 256
|
||||
* @param {number} [options.colors=256] - alternative spelling of `options.colours`
|
||||
* @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 10 (slowest)
|
||||
@ -575,10 +575,11 @@ function webp (options) {
|
||||
*/
|
||||
function gif (options) {
|
||||
if (is.object(options)) {
|
||||
if (is.defined(options.reoptimise)) {
|
||||
this._setBooleanOption('gifReoptimise', options.reoptimise);
|
||||
} else if (is.defined(options.reoptimize)) {
|
||||
this._setBooleanOption('gifReoptimise', options.reoptimize);
|
||||
if (is.defined(options.reuse)) {
|
||||
this._setBooleanOption('gifReuse', options.reuse);
|
||||
}
|
||||
if (is.defined(options.progressive)) {
|
||||
this._setBooleanOption('gifProgressive', options.progressive);
|
||||
}
|
||||
const colours = options.colours || options.colors;
|
||||
if (is.defined(colours)) {
|
||||
@ -690,7 +691,7 @@ function jp2 (options) {
|
||||
}
|
||||
if (is.defined(options.chromaSubsampling)) {
|
||||
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
|
||||
this.options.heifChromaSubsampling = options.chromaSubsampling;
|
||||
this.options.jp2ChromaSubsampling = options.chromaSubsampling;
|
||||
} else {
|
||||
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
|
||||
}
|
||||
|
24
package.json
24
package.json
@ -155,19 +155,19 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"config": {
|
||||
"libvips": "8.13.3",
|
||||
"libvips": "8.14.0-rc1",
|
||||
"integrity": {
|
||||
"darwin-arm64v8": "sha512-xFgYt7CtQSZcWoyUdzPTDNHbioZIrZSEU+gkMxzH4Cgjhi4/N49UsonnIZhKQoTBGloAqEexHeMx4rYTQ2Kgvw==",
|
||||
"darwin-x64": "sha512-6SivWKzu15aUMMohe0wg7sNYMPETVnOe40BuWsnKOgzl3o5FpQqNSgs+68Mi8Za3Qti9/DaR+H/fyD0x48Af2w==",
|
||||
"linux-arm64v8": "sha512-b+iI9V/ehgDabXYRQcvqa5CEysh+1FQsgFmYc358StCrJCDahwNmsQdsiH1GOVd5WaWh5wHUGByPwMmFOO16Aw==",
|
||||
"linux-armv6": "sha512-zRP2F+EiustLE4bXSH8AHCxwfemh9d+QuvmPjira/HL6uJOUuA7SyQgVV1TPwTQle2ioCNnKPm7FEB/MAiT+ug==",
|
||||
"linux-armv7": "sha512-6OCChowE5lBXXXAZrnGdA9dVktg7UdODEBpE5qTroiAJYZv4yXRMgyDFYajok7du2NTgoklhxGk8d9+4vGv5hg==",
|
||||
"linux-x64": "sha512-OTmlmP2r8ozGKdB96X+K5oQE1ojVZanqLqqKlwDpEnfixyIaDGYbVzcjWBNGU3ai/26bvkaCkjynnc2ecYcsuA==",
|
||||
"linuxmusl-arm64v8": "sha512-Qh5Wi+bkKTohFYHzSPssfjMhIkD6z6EHbVmnwmWSsgY9zsUBStFp6+mKcNTQfP5YM5Mz06vJOkLHX2OzEr5TzA==",
|
||||
"linuxmusl-x64": "sha512-DwB4Fs3+ISw9etaLCANkueZDdk758iOS+wNp4TKZkHdq0al6B/3Pk7OHLR8a9E3H6wYDD328u++dcJzip5tacA==",
|
||||
"win32-arm64v8": "sha512-96r3W+O4BtX602B1MtxU5Ru4lKzRRTZqM4OQEBJ//TNL3fiCZdd9agD+RQBjaeR4KFIyBSt3F7IE425ZWmxz+w==",
|
||||
"win32-ia32": "sha512-qfN1MsfQGek1QQd1UNW7JT+5K5Ne1suFQ2GpgpYm3JLSpIve/tz2vOGEGzvTVssOBADJvAkTDFt+yIi3PgU9pA==",
|
||||
"win32-x64": "sha512-eb3aAmjbVVBVRbiYgebQwoxkAt69WI8nwmKlilSQ3kWqoc0pXfIe322rF2UR8ebbISCGvYRUfzD2r1k92RXISQ=="
|
||||
"darwin-arm64v8": "sha512-WWVRbtTdBGx7l0mZ1RkMsNzVkiR3923knivO21RKyRm2q6PJZunAd9Da3wVBfGnofhirlsbRkQLwPbFsdq/lkA==",
|
||||
"darwin-x64": "sha512-tyYkU/Mma1LKbg2PQELpoeECw/SOp5BqKwasIuEAlddC7g1JWLpIYrxuAbH1kaWy3soEFBJbN1CxRNL0YWy9Ug==",
|
||||
"linux-arm64v8": "sha512-m7yr3ZSL3NlEpDOlUrScTYR4Rj1b5cSt8PmWvIkOtEGRJjtvFufurCDroOaaOIdKi1uB5n23ziB2PwTZX7tyAA==",
|
||||
"linux-armv6": "sha512-dy2t/7uyqjKXCgiYDbrouFp3pNqpzsPNpgkk3uT/c3wAhNcRvpVHbYMMrau0o/o9YULLLQ5aBW9HgEvjHCaqZw==",
|
||||
"linux-armv7": "sha512-5bJhPzDrX3IaWU9Z3qMtE/C20bFAynN9YhaPF8gqFBMRkyif1ZnAlZl6PlVg/c968ABB4vJcAQJf4ImZJvBZLQ==",
|
||||
"linux-x64": "sha512-13nlg8oc0V/uxFa7r+QIJpIOVZstxM2CE1LSUI7SUmy4h6h+Xf0ztMi+6w+kL7LibtLWpjTEHQuCBNxSWdt2VA==",
|
||||
"linuxmusl-arm64v8": "sha512-3RrraBIynOBDQuKwhiDrulRXZh1BfiDfy2SIyEgkPC301UdGw4FHQntgYc9E6K9CzYGv8jb1S9/8hcrn2/+LyA==",
|
||||
"linuxmusl-x64": "sha512-K+5eujn+pgH/vDcAJrtbTfZxJn9W9pfvJlTrtF0AjZdOBMwt9fcCeCeNVvKzKYcemzFmBHsjqxkgqlxA4xEnXQ==",
|
||||
"win32-arm64v8": "sha512-VliwICXWqGERjk2I3wsw6qwFVtHZZ9jljNW8Xev51M9Y/gdttzVk+fWqiikhJD5K2Gp5sg1ccbvEsu42ZVQXxA==",
|
||||
"win32-ia32": "sha512-dNJoDRDkYzkNCz0gGtIahOf8n2g+dBg0iNVHvYDAJV7qLfjAqtfQJZ9TG2p4PzPCM2H4kazSNL/JOxFF4bpc1g==",
|
||||
"win32-x64": "sha512-myvHzlVgjztJ//crm8daXyGUa7ZciRfj3+L/faqyZsX2FMr4SImw4OO2UkCvDLJz6Fxar4biau3kAeGDJLCIQw=="
|
||||
},
|
||||
"runtime": "napi",
|
||||
"target": 7
|
||||
|
@ -167,6 +167,9 @@ namespace sharp {
|
||||
if (HasAttr(input, "textSpacing")) {
|
||||
descriptor->textSpacing = AttrAsUint32(input, "textSpacing");
|
||||
}
|
||||
if (HasAttr(input, "textWrap")) {
|
||||
descriptor->textWrap = AttrAsEnum<VipsTextWrap>(input, "textWrap", VIPS_TYPE_TEXT_WRAP);
|
||||
}
|
||||
}
|
||||
// Limit input images to a given number of pixels, where pixels = width * height
|
||||
descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));
|
||||
@ -454,6 +457,7 @@ namespace sharp {
|
||||
->set("justify", descriptor->textJustify)
|
||||
->set("rgba", descriptor->textRgba)
|
||||
->set("spacing", descriptor->textSpacing)
|
||||
->set("wrap", descriptor->textWrap)
|
||||
->set("autofit_dpi", &descriptor->textAutofitDpi);
|
||||
if (descriptor->textWidth > 0) {
|
||||
textOptions->set("width", descriptor->textWidth);
|
||||
@ -612,6 +616,15 @@ namespace sharp {
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove GIF palette from image.
|
||||
*/
|
||||
VImage RemoveGifPalette(VImage image) {
|
||||
VImage copy = image.copy();
|
||||
copy.remove("gif-palette");
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*
|
||||
Does this image have a non-default density?
|
||||
*/
|
||||
|
13
src/common.h
13
src/common.h
@ -25,9 +25,9 @@
|
||||
// Verify platform and compiler compatibility
|
||||
|
||||
#if (VIPS_MAJOR_VERSION < 8) || \
|
||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 13) || \
|
||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 13 && VIPS_MICRO_VERSION < 3)
|
||||
#error "libvips version 8.13.3+ is required - please see https://sharp.pixelplumbing.com/install"
|
||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 14) || \
|
||||
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 14 && VIPS_MICRO_VERSION < 0)
|
||||
#error "libvips version 8.14.0+ is required - please see https://sharp.pixelplumbing.com/install"
|
||||
#endif
|
||||
|
||||
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
||||
@ -81,6 +81,7 @@ namespace sharp {
|
||||
int textDpi;
|
||||
bool textRgba;
|
||||
int textSpacing;
|
||||
VipsTextWrap textWrap;
|
||||
int textAutofitDpi;
|
||||
|
||||
InputDescriptor():
|
||||
@ -114,6 +115,7 @@ namespace sharp {
|
||||
textDpi(72),
|
||||
textRgba(FALSE),
|
||||
textSpacing(0),
|
||||
textWrap(VIPS_TEXT_WRAP_WORD),
|
||||
textAutofitDpi(0) {}
|
||||
};
|
||||
|
||||
@ -255,6 +257,11 @@ namespace sharp {
|
||||
*/
|
||||
VImage RemoveAnimationProperties(VImage image);
|
||||
|
||||
/*
|
||||
Remove GIF palette from image.
|
||||
*/
|
||||
VImage RemoveGifPalette(VImage image);
|
||||
|
||||
/*
|
||||
Does this image have a non-default density?
|
||||
*/
|
||||
|
@ -3679,6 +3679,13 @@ VipsBlob *VImage::webpsave_buffer( VOption *options ) const
|
||||
return( buffer );
|
||||
}
|
||||
|
||||
void VImage::webpsave_mime( VOption *options ) const
|
||||
{
|
||||
call( "webpsave_mime",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this ) );
|
||||
}
|
||||
|
||||
void VImage::webpsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "webpsave_target",
|
||||
|
@ -80,6 +80,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
||||
if (image.get_typeof(VIPS_META_RESOLUTION_UNIT) == VIPS_TYPE_REF_STRING) {
|
||||
baton->resolutionUnit = image.get_string(VIPS_META_RESOLUTION_UNIT);
|
||||
}
|
||||
if (image.get_typeof("magick-format") == VIPS_TYPE_REF_STRING) {
|
||||
baton->formatMagick = image.get_string("magick-format");
|
||||
}
|
||||
if (image.get_typeof("openslide.level-count") == VIPS_TYPE_REF_STRING) {
|
||||
int const levels = std::stoi(image.get_string("openslide.level-count"));
|
||||
for (int l = 0; l < levels; l++) {
|
||||
@ -204,6 +207,9 @@ class MetadataWorker : public Napi::AsyncWorker {
|
||||
if (!baton->resolutionUnit.empty()) {
|
||||
info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit);
|
||||
}
|
||||
if (!baton->formatMagick.empty()) {
|
||||
info.Set("formatMagick", baton->formatMagick);
|
||||
}
|
||||
if (!baton->levels.empty()) {
|
||||
int i = 0;
|
||||
Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
|
||||
|
@ -41,6 +41,7 @@ struct MetadataBaton {
|
||||
int pagePrimary;
|
||||
std::string compression;
|
||||
std::string resolutionUnit;
|
||||
std::string formatMagick;
|
||||
std::vector<std::pair<int, int>> levels;
|
||||
int subifds;
|
||||
std::vector<double> background;
|
||||
|
@ -409,6 +409,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
image = image.bandjoin(joinImage);
|
||||
}
|
||||
image = image.copy(VImage::option()->set("interpretation", baton->colourspace));
|
||||
image = sharp::RemoveGifPalette(image);
|
||||
}
|
||||
|
||||
inputWidth = image.width();
|
||||
@ -660,6 +661,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
ys.push_back(top);
|
||||
}
|
||||
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
|
||||
image = sharp::RemoveGifPalette(image);
|
||||
}
|
||||
|
||||
// Gamma decoding (brighten)
|
||||
@ -689,6 +691,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean);
|
||||
booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspaceInput);
|
||||
image = sharp::Boolean(image, booleanImage, baton->booleanOp);
|
||||
image = sharp::RemoveGifPalette(image);
|
||||
}
|
||||
|
||||
// Apply per-channel Bandbool bitwise operations after all other operations
|
||||
@ -870,7 +873,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
->set("strip", !baton->withMetadata)
|
||||
->set("bitdepth", baton->gifBitdepth)
|
||||
->set("effort", baton->gifEffort)
|
||||
->set("reoptimise", baton->gifReoptimise)
|
||||
->set("reuse", baton->gifReuse)
|
||||
->set("interlace", baton->gifProgressive)
|
||||
->set("interframe_maxerror", baton->gifInterFrameMaxError)
|
||||
->set("interpalette_maxerror", baton->gifInterPaletteMaxError)
|
||||
->set("dither", baton->gifDither)));
|
||||
@ -1068,7 +1072,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
->set("strip", !baton->withMetadata)
|
||||
->set("bitdepth", baton->gifBitdepth)
|
||||
->set("effort", baton->gifEffort)
|
||||
->set("reoptimise", baton->gifReoptimise)
|
||||
->set("reuse", baton->gifReuse)
|
||||
->set("interlace", baton->gifProgressive)
|
||||
->set("dither", baton->gifDither));
|
||||
baton->formatOut = "gif";
|
||||
} else if (baton->formatOut == "tiff" || (mightMatchInput && isTiff) ||
|
||||
@ -1582,7 +1587,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->gifDither = sharp::AttrAsDouble(options, "gifDither");
|
||||
baton->gifInterFrameMaxError = sharp::AttrAsDouble(options, "gifInterFrameMaxError");
|
||||
baton->gifInterPaletteMaxError = sharp::AttrAsDouble(options, "gifInterPaletteMaxError");
|
||||
baton->gifReoptimise = sharp::AttrAsBool(options, "gifReoptimise");
|
||||
baton->gifReuse = sharp::AttrAsBool(options, "gifReuse");
|
||||
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
|
||||
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
|
||||
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
|
||||
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
|
||||
|
@ -165,7 +165,8 @@ struct PipelineBaton {
|
||||
double gifDither;
|
||||
double gifInterFrameMaxError;
|
||||
double gifInterPaletteMaxError;
|
||||
bool gifReoptimise;
|
||||
bool gifReuse;
|
||||
bool gifProgressive;
|
||||
int tiffQuality;
|
||||
VipsForeignTiffCompression tiffCompression;
|
||||
VipsForeignTiffPredictor tiffPredictor;
|
||||
@ -322,7 +323,8 @@ struct PipelineBaton {
|
||||
gifDither(1.0),
|
||||
gifInterFrameMaxError(0.0),
|
||||
gifInterPaletteMaxError(3.0),
|
||||
gifReoptimise(false),
|
||||
gifReuse(true),
|
||||
gifProgressive(false),
|
||||
tiffQuality(80),
|
||||
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
|
||||
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
|
||||
|
@ -80,19 +80,36 @@ describe('GIF input', () => {
|
||||
assert.strictEqual(true, reduced.length < original.length);
|
||||
});
|
||||
|
||||
it('valid optimise', () => {
|
||||
assert.doesNotThrow(() => sharp().gif({ reoptimise: true }));
|
||||
assert.doesNotThrow(() => sharp().gif({ reoptimize: true }));
|
||||
it('valid reuse', () => {
|
||||
assert.doesNotThrow(() => sharp().gif({ reuse: true }));
|
||||
assert.doesNotThrow(() => sharp().gif({ reuse: false }));
|
||||
});
|
||||
|
||||
it('invalid reoptimise throws', () => {
|
||||
it('invalid reuse throws', () => {
|
||||
assert.throws(
|
||||
() => sharp().gif({ reoptimise: -1 }),
|
||||
/Expected boolean for gifReoptimise but received -1 of type number/
|
||||
() => sharp().gif({ reuse: -1 }),
|
||||
/Expected boolean for gifReuse but received -1 of type number/
|
||||
);
|
||||
assert.throws(
|
||||
() => sharp().gif({ reoptimize: 'fail' }),
|
||||
/Expected boolean for gifReoptimise but received fail of type string/
|
||||
() => sharp().gif({ reuse: 'fail' }),
|
||||
/Expected boolean for gifReuse but received fail of type string/
|
||||
);
|
||||
});
|
||||
|
||||
it('progressive changes file size', async () => {
|
||||
const nonProgressive = await sharp(fixtures.inputGif).gif({ progressive: false }).toBuffer();
|
||||
const progressive = await sharp(fixtures.inputGif).gif({ progressive: true }).toBuffer();
|
||||
assert(nonProgressive.length !== progressive.length);
|
||||
});
|
||||
|
||||
it('invalid progressive throws', () => {
|
||||
assert.throws(
|
||||
() => sharp().gif({ progressive: -1 }),
|
||||
/Expected boolean for gifProgressive but received -1 of type number/
|
||||
);
|
||||
assert.throws(
|
||||
() => sharp().gif({ progressive: 'fail' }),
|
||||
/Expected boolean for gifProgressive but received fail of type string/
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -294,4 +294,24 @@ describe('Text to image', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('valid wrap throws', () => {
|
||||
assert.doesNotThrow(() => sharp({ text: { text: 'text', wrap: 'none' } }));
|
||||
assert.doesNotThrow(() => sharp({ text: { text: 'text', wrap: 'wordChar' } }));
|
||||
});
|
||||
|
||||
it('invalid wrap throws', () => {
|
||||
assert.throws(
|
||||
() => sharp({ text: { text: 'text', wrap: 1 } }),
|
||||
/Expected one of: word, char, wordChar, none for text\.wrap but received 1 of type number/
|
||||
);
|
||||
assert.throws(
|
||||
() => sharp({ text: { text: 'text', wrap: false } }),
|
||||
/Expected one of: word, char, wordChar, none for text\.wrap but received false of type boolean/
|
||||
);
|
||||
assert.throws(
|
||||
() => sharp({ text: { text: 'text', wrap: 'invalid' } }),
|
||||
/Expected one of: word, char, wordChar, none for text\.wrap but received invalid of type string/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user