diff --git a/docs/api-output.md b/docs/api-output.md index 96e5f6f0..d2d2d259 100644 --- a/docs/api-output.md +++ b/docs/api-output.md @@ -303,7 +303,7 @@ const data = await sharp(input) - Throws **[Error][4]** unsupported format or options -Returns **Sharp** +Returns **Sharp** ## tile @@ -315,10 +315,11 @@ Warning: multiple sharp instances concurrently producing tile output can expose ### Parameters -- `options` **[Object][6]?** +- `options` **[Object][6]?** - `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.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'`) @@ -359,3 +360,5 @@ Returns **Sharp** [8]: https://nodejs.org/api/buffer.html [9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number + +[10]: https://www.npmjs.org/package/color diff --git a/lib/constructor.js b/lib/constructor.js index bfbfebad..3736aef2 100644 --- a/lib/constructor.js +++ b/lib/constructor.js @@ -213,6 +213,7 @@ const Sharp = function (input, options) { tileSize: 256, tileOverlap: 0, tileSkipBlanks: -1, + tileBackground: [255, 255, 255, 255], linearA: 1, linearB: 0, // Function to notify of libvips warnings diff --git a/lib/output.js b/lib/output.js index b37664a2..0e72d445 100644 --- a/lib/output.js +++ b/lib/output.js @@ -551,6 +551,7 @@ function toFormat (format, options) { * @param {Number} [options.size=256] tile size in pixels, a value between 1 and 8192. * @param {Number} [options.overlap=0] tile overlap in pixels, a value between 0 and 8192. * @param {Number} [options.angle=0] tile angle of rotation, must be a multiple of 90. + * @param {String|Object} [options.background={r: 255, g: 255, b: 255, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to white without transparency. * @param {String} [options.depth] how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout. * @param {Number} [options.skipBlanks=-1] threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images * @param {String} [options.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file). @@ -603,6 +604,8 @@ function tile (options) { throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle); } } + // Background colour + this._setBackgroundColourOption('tileBackground', options.background); // Depth of tiles if (is.defined(options.depth)) { if (is.string(options.depth) && is.inArray(options.depth, ['onepixel', 'onetile', 'one'])) { diff --git a/package.json b/package.json index 891fcca0..cd4f9684 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "Michael B. Klein ", "Jordan Prudhomme ", "Ilya Ovdin ", - "Andargor " + "Andargor ", + "Paul Neave " ], "scripts": { "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)", diff --git a/src/pipeline.cc b/src/pipeline.cc index 8cd3b89c..f13a218c 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -959,6 +959,11 @@ class PipelineWorker : public Nan::AsyncWorker { }; suffix = AssembleSuffixString(extname, options); } + + // Remove alpha channel from tile background if image does not contain an alpha channel + if (!HasAlpha(image)) { + baton->tileBackground.pop_back(); + } // Write DZ to file vips::VOption *options = VImage::option() ->set("strip", !baton->withMetadata) @@ -968,6 +973,7 @@ class PipelineWorker : public Nan::AsyncWorker { ->set("layout", baton->tileLayout) ->set("suffix", const_cast(suffix.data())) ->set("angle", CalculateAngleRotation(baton->tileAngle)) + ->set("background", baton->tileBackground) ->set("skip_blanks", baton->tileSkipBlanks); // libvips chooses a default depth based on layout. Instead of replicating that logic here by @@ -1374,6 +1380,7 @@ NAN_METHOD(pipeline) { baton->tileOverlap = AttrTo(options, "tileOverlap"); std::string tileContainer = AttrAsStr(options, "tileContainer"); baton->tileAngle = AttrTo(options, "tileAngle"); + baton->tileBackground = AttrAsRgba(options, "tileBackground"); baton->tileSkipBlanks = AttrTo(options, "tileSkipBlanks"); if (tileContainer == "zip") { baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP; diff --git a/src/pipeline.h b/src/pipeline.h index 18db0be3..3900e0fa 100644 --- a/src/pipeline.h +++ b/src/pipeline.h @@ -175,6 +175,7 @@ struct PipelineBaton { VipsForeignDzLayout tileLayout; std::string tileFormat; int tileAngle; + std::vector tileBackground; int tileSkipBlanks; VipsForeignDzDepth tileDepth; std::unique_ptr recombMatrix; @@ -280,6 +281,7 @@ struct PipelineBaton { tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS), tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ), tileAngle(0), + tileBackground{ 255.0, 255.0, 255.0, 255.0 }, tileSkipBlanks(-1), tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {} };