UNPKG

imagemagick-async

Version:
741 lines (634 loc) 17.4 kB
let ComposeBaseClass = require('./composebaseclass.js').ComposeBaseClass; //------------------------------------------ // CONSTANTS const MIN_FILEPATHS = 2; //------------------------------------------- // COMPOSITE class Composite extends ComposeBaseClass { constructor(filepaths, gravity) { super(); this.filepaths_ = filepaths; this.gravity_ = gravity; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { let args = []; if (this.gravity_) args.push('-gravity', this.gravity_); // Add first 2 paths args.push(this.filepaths_[0], this.filepaths_[1]); // Add other parts accordingly for (let i = 2; i < this.filepaths_.length; ++i) { args.push('-composite', this.filepaths_[i]); } args.push('-composite'); return args; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * @override */ NumberOfSources() { return 0; } /** * @override */ Name() { return 'Composite'; } /** * Create a Composite object. Creates a single image from a list of provided images. The first image is the bottom-most layer and the last image is the top-most layer. * @param {Array<string>} filepaths * @returns {Composite} Returns a Composite object. If inputs are invalid, it returns null. */ static Create(filepaths, gravity) { if (!filepaths || filepaths.length < 2) return null; return new Composite(filepaths, gravity); } } //-------------------------------------- // MULTIPLY (white transparency) class MultiplyWhiteTransparency extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return ['-compose', 'Multiply', this.src1_, this.src2_, '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'MultiplyWhiteTransparency'; } /** * Create a MultiplyWhiteTransparency object. Overlay colors of image with white background onto the other. Overlaying colors attenuate to black. That is, this operation only darkens colors (never lightens them). NOTE: Black will result in black. * @param {string} src1 * @param {string} src2 * @returns {MultiplyWhiteTransparency} Returns a MultiplyWhiteTransparency object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new MultiplyWhiteTransparency(src1, src2); } } //-------------------------------------- // MULTIPLY (black transparency) class MultiplyBlackTransparency extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return ['-compose', 'Screen', this.src1_, this.src2_, '-composite']; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'MultiplyBlackTransparency'; } /** * Create a MultiplyBlackTransparency object. Overlay colors of image with black background onto the other. Overlaying colors attenuate to white. That is, this operation only lightens colors (never darkens them). NOTE: White will result in white. * @param {string} src1 * @param {string} src2 * @returns {MultiplyBlackTransparency} Returns a MultiplyBlackTransparency object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new MultiplyBlackTransparency(src1, src2); } } //-------------------------------------- // ADD class Add extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return ['-compose', 'plus', this.src1_, this.src2_, '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Add'; } /** * Create an Add object. Blend the images equally. All overlapping pixel colors are added together. * @param {string} src1 * @param {string} src2 * @returns {Add} Returns an Add object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Add(src1, src2); } } //-------------------------------------- // SUBTRACT class Subtract extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return ['-compose', 'minus', this.src1_, this.src2_, '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Subtract'; } /** * Create a Subtract object. Subtract one image from the other: src1 - src2. Overlapping pixel colors are subtracted. * @param {string} src1 * @param {string} src2 * @returns {Subtract} Returns a Subtract object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Subtract(src1, src2); } } //-------------------------------------- // SET THEORY class Union extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return [this.src1_, this.src2_, '-compose', 'Lighten', '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Union'; } /** * Create a Union object. Get the union of pixels. If images are colored, intersecting pixel colors are added. (Best used with black and white images/masks) * @param {string} src1 * @param {string} src2 * @returns {Union} Returns a Union object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Union(src1, src2); } } class Intersection extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return [this.src1_, this.src2_, '-compose', 'Darken', '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Intersection'; } /** * Create an Intersection object. Get the intersection of pixels. If images are colored, the intersecting pixels are blacked out. (Best used with black and white images/masks) * @param {string} src1 * @param {string} src2 * @returns {Intersectionion} Returns an Intersection object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Intersection(src1, src2); } } class Difference extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return [this.src1_, this.src2_, '-compose', 'Difference', '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Difference'; } /** * Create a Difference object. Get the difference (XOR) of pixels. If images are colored, it produces same result as the Union operator. (Best used with black and white images/masks) * @param {string} src1 * @param {string} src2 * @returns {Difference} Returns a Difference object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Difference(src1, src2); } } class Exclusion extends ComposeBaseClass { constructor(src1, src2) { super(); this.src1_ = src1; this.src2_ = src2; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { return [this.src1_, this.src2_, '-compose', 'Minus_Src', '-composite']; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'Exclusion'; } /** * Create an Exclusion object. Get the exclusion (relative complement) of pixels. Results in A-B => Everything in A that is NOT in B. If the images are colored, the result is src2 overlapping src1. (Best used with black and white images/masks) * @param {string} src1 * @param {string} src2 * @returns {Exclusion} Returns a Exclusion object. If inputs are invalid, it returns null. */ static Create(src1, src2) { if (!src1 || !src2) return null; return new Exclusion(src1, src2); } } //-------------------------------------- // MASKS class ChangedPixels extends ComposeBaseClass { constructor(src1, src2, fuzz) { super(); this.src1_ = src1; this.src2_ = src2; this.fuzz_ = fuzz; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { let args = [this.src1_, this.src2_]; if (this.fuzz_) args.push('-fuzz', `${this.fuzz_}%`); args.push('-compose', 'ChangeMask', '-composite'); return args; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'ChangedPixels'; } /** * Create an ChangedPixels object. Make specific pixels fully transparent. That is, the pixels in src2 that match those in src1 will become transparent. * @param {string} src1 * @param {string} src2 * @param {number} fuzz (Optional) Value between 1 and 100 that helps group similar colors together. (Small values help with slight color variations) * @returns {ChangedPixels} Returns a ChangedPixels object. If inputs are invalid, it returns null. */ static Create(src1, src2, fuzz) { if (!src1 || !src2) return null; return new ChangedPixels(src1, src2, fuzz); } } class UnchangedPixels extends ComposeBaseClass { constructor(src1, src2, fuzz) { super(); this.src1_ = src1; this.src2_ = src2; this.fuzz_ = fuzz; } /** * @returns {Array<string|number>} Returns an array of image magick arguments associated with this layer. */ Args() { let args = [this.src1_, this.src2_]; if (this.fuzz_) args.push('-fuzz', `${this.fuzz_}%`); args.push('-compose', 'ChangeMask', '-composite', '-channel', 'A', '-negate'); return args; } /** * @override */ NumberOfSources() { return 2; } /** * @returns {Array<string|number>} Returns an array of arguments used for rendering this layer. */ RenderArgs() { return this.Args(); } /** * Replace current source with new source. */ UpdateSources(newSources) { for (let i = 0; i < this.NumberOfSources(); ++i) { let currNewSrc = newSources[i]; if (currNewSrc) { let variableName = `src${i + 1}_`; this[variableName] = currNewSrc; } } } /** * @override */ Name() { return 'UnchangedPixels'; } /** * Create an UnchangedPixels object. Get an image showing the similarities between two images. * @param {string} src1 * @param {string} src2 * @param {number} fuzz (Optional) Value between 1 and 100 that helps group similar colors together. (Small values help with slight color variations) * @returns {UnchangedPixels} Returns a UnchangedPixels object. If inputs are invalid, it returns null. */ static Create(src1, src2, fuzz) { if (!src1 || !src2) return null; return new UnchangedPixels(src1, src2, fuzz); } } //--------------------------------------- // EXPORTS exports.CreateCompositeMod = Composite.Create; exports.CreateMultiplyWhiteTransparencyMod = MultiplyWhiteTransparency.Create; exports.CreateMultiplyBlackTransparencyMod = MultiplyBlackTransparency.Create; exports.CreateAddMod = Add.Create; exports.CreateSubtractMod = Subtract.Create; exports.CreateUnionMod = Union.Create; exports.CreateIntersectionMod = Intersection.Create; exports.CreateDifferenceMod = Difference.Create; exports.CreateExclusionMod = Exclusion.Create; exports.CreateChangedPixelsMod = ChangedPixels.Create; exports.CreateUnchangedPixelsMod = UnchangedPixels.Create;