Deprecate background, add op-specific prop to resize/extend/flatten #1392

This commit is contained in:
Lovell Fuller
2018-10-01 20:58:55 +01:00
parent 6007e13a22
commit a64844689e
17 changed files with 378 additions and 296 deletions

View File

@@ -1,5 +1,7 @@
'use strict';
const deprecate = require('util').deprecate;
const color = require('color');
const is = require('./is');
@@ -16,25 +18,20 @@ const colourspace = {
};
/**
* Set the background for the `embed`, `flatten` and `extend` operations.
* The default background is `{r: 0, g: 0, b: 0, alpha: 1}`, black without transparency.
*
* Delegates to the _color_ module, which can throw an Error
* but is liberal in what it accepts, clipping values to sensible min/max.
* The alpha value is a float between `0` (transparent) and `1` (opaque).
*
* @param {String|Object} rgba - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
* @returns {Sharp}
* @throws {Error} Invalid parameter
* @deprecated
* @private
*/
function background (rgba) {
const colour = color(rgba);
this.options.background = [
const background = [
colour.red(),
colour.green(),
colour.blue(),
Math.round(colour.alpha() * 255)
];
this.options.resizeBackground = background;
this.options.extendBackground = background;
this.options.flattenBackground = background.slice(0, 3);
return this;
}
@@ -102,23 +99,45 @@ function toColorspace (colorspace) {
return this.toColourspace(colorspace);
}
/**
* Update a colour attribute of the this.options Object.
* @private
* @param {String} key
* @param {String|Object} val
* @throws {Error} Invalid key
*/
function _setColourOption (key, val) {
if (is.object(val) || is.string(val)) {
const colour = color(val);
this.options[key] = [
colour.red(),
colour.green(),
colour.blue(),
Math.round(colour.alpha() * 255)
];
}
}
/**
* Decorate the Sharp prototype with colour-related functions.
* @private
*/
module.exports = function (Sharp) {
// Public instance functions
[
background,
// Public
tint,
greyscale,
grayscale,
toColourspace,
toColorspace
toColorspace,
// Private
_setColourOption
].forEach(function (f) {
Sharp.prototype[f.name] = f;
});
// Class attributes
Sharp.colourspace = colourspace;
Sharp.colorspace = colourspace;
// Deprecated
Sharp.prototype.background = deprecate(background, 'background(background) is deprecated, use resize({ background }), extend({ background }) or flatten({ background }) instead');
};

View File

@@ -105,6 +105,7 @@ const Sharp = function (input, options) {
height: -1,
canvas: 'crop',
position: 0,
resizeBackground: [0, 0, 0, 255],
useExifOrientation: false,
angle: 0,
rotationAngle: 0,
@@ -116,14 +117,15 @@ const Sharp = function (input, options) {
extendBottom: 0,
extendLeft: 0,
extendRight: 0,
extendBackground: [0, 0, 0, 255],
withoutEnlargement: false,
kernel: 'lanczos3',
fastShrinkOnLoad: true,
// operations
background: [0, 0, 0, 255],
tintA: 128,
tintB: 128,
flatten: false,
flattenBackground: [0, 0, 0],
negate: false,
medianSize: 0,
blurSigma: 0,

View File

@@ -171,12 +171,15 @@ function blur (sigma) {
}
/**
* Merge alpha transparency channel, if any, with `background`.
* @param {Boolean} [flatten=true]
* Merge alpha transparency channel, if any, with a background.
* @param {String|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black.
* @returns {Sharp}
*/
function flatten (flatten) {
this.options.flatten = is.bool(flatten) ? flatten : true;
function flatten (options) {
this.options.flatten = is.bool(options) ? options : true;
if (is.object(options)) {
this._setColourOption('flattenBackground', options.background);
}
return this;
}

View File

@@ -130,18 +130,18 @@ const mapFitToCanvas = {
* });
*
* @example
* sharp(inputBuffer)
* sharp(input)
* .resize(200, 300, {
* kernel: sharp.kernel.nearest,
* fit: 'contain',
* position: 'right top'
* position: 'right top',
* background: { r: 255, g: 255, b: 255, alpha: 0.5 }
* })
* .background('white')
* .toFile('output.tiff')
* .toFile('output.png')
* .then(() => {
* // output.tiff is a 200 pixels wide and 300 pixels high image
* // output.png is a 200 pixels wide and 300 pixels high image
* // containing a nearest-neighbour scaled version
* // embedded in the north-east corner of a white canvas
* // contained within the north-east corner of a semi-transparent white canvas
* });
*
* @example
@@ -159,7 +159,7 @@ const mapFitToCanvas = {
* .pipe(writableStream);
*
* @example
* sharp(inputBuffer)
* sharp(input)
* .resize(200, 200, {
* fit: sharp.fit.inside,
* withoutEnlargement: true
@@ -178,6 +178,7 @@ const mapFitToCanvas = {
* @param {String} [options.height] - alternative means of specifying `height`. If both are present this take priority.
* @param {String} [options.fit='cover'] - how the image should be resized to fit both provided dimensions, one of `cover`, `contain`, `fill`, `inside` or `outside`.
* @param {String} [options.position='centre'] - position, gravity or strategy to use when `fit` is `cover` or `contain`.
* @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when using a `fit` of `contain`, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
* @param {String} [options.kernel='lanczos3'] - the kernel to use for image reduction.
* @param {Boolean} [options.withoutEnlargement=false] - do not enlarge if the width *or* height are already less than the specified dimensions, equivalent to GraphicsMagick's `>` geometry option.
* @param {Boolean} [options.fastShrinkOnLoad=true] - take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern on some images.
@@ -234,6 +235,10 @@ function resize (width, height, options) {
throw is.invalidParameterError('position', 'valid position/gravity/strategy', options.position);
}
}
// Background
if (is.defined(options.background)) {
this._setColourOption('resizeBackground', options.background);
}
// Kernel
if (is.defined(options.kernel)) {
if (is.string(kernel[options.kernel])) {
@@ -255,7 +260,7 @@ function resize (width, height, options) {
}
/**
* Extends/pads the edges of the image with the colour provided to the `background` method.
* Extends/pads the edges of the image with the provided background colour.
* This operation will always occur after resizing and extraction, if any.
*
* @example
@@ -263,8 +268,14 @@ function resize (width, height, options) {
* // to the top, left and right edges and 20 to the bottom edge
* sharp(input)
* .resize(140)
* .background({r: 0, g: 0, b: 0, alpha: 0})
* .extend({top: 10, bottom: 20, left: 10, right: 10})
* .)
* .extend({
* top: 10,
* bottom: 20,
* left: 10,
* right: 10
* background: { r: 0, g: 0, b: 0, alpha: 0 }
* })
* ...
*
* @param {(Number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts
@@ -272,6 +283,7 @@ function resize (width, height, options) {
* @param {Number} [extend.left]
* @param {Number} [extend.bottom]
* @param {Number} [extend.right]
* @param {String|Object} [extend.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
@@ -292,6 +304,7 @@ function extend (extend) {
this.options.extendBottom = extend.bottom;
this.options.extendLeft = extend.left;
this.options.extendRight = extend.right;
this._setColourOption('extendBackground', extend.background);
} else {
throw new Error('Invalid edge extension ' + extend);
}