Path: blob/master/node_modules/@jimp/core/dist/index.js
1126 views
"use strict";12var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");34var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");56Object.defineProperty(exports, "__esModule", {7value: true8});9exports.addConstants = addConstants;10exports.addJimpMethods = addJimpMethods;11exports.jimpEvMethod = jimpEvMethod;12exports.jimpEvChange = jimpEvChange;13Object.defineProperty(exports, "addType", {14enumerable: true,15get: function get() {16return MIME.addType;17}18});19exports["default"] = void 0;2021var _construct2 = _interopRequireDefault(require("@babel/runtime/helpers/construct"));2223var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));2425var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));2627var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));2829var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));3031var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));3233var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));3435var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));3637var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));3839var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));4041var _fs = _interopRequireDefault(require("fs"));4243var _path = _interopRequireDefault(require("path"));4445var _events = _interopRequireDefault(require("events"));4647var _utils = require("@jimp/utils");4849var _anyBase = _interopRequireDefault(require("any-base"));5051var _mkdirp = _interopRequireDefault(require("mkdirp"));5253var _pixelmatch = _interopRequireDefault(require("pixelmatch"));5455var _tinycolor = _interopRequireDefault(require("tinycolor2"));5657var _phash = _interopRequireDefault(require("./modules/phash"));5859var _request = _interopRequireDefault(require("./request"));6061var _composite = _interopRequireDefault(require("./composite"));6263var _promisify = _interopRequireDefault(require("./utils/promisify"));6465var MIME = _interopRequireWildcard(require("./utils/mime"));6667var _imageBitmap = require("./utils/image-bitmap");6869var constants = _interopRequireWildcard(require("./constants"));7071var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'; // an array storing the maximum string length of hashes at various bases72// 0 and 1 do not exist as possible hash lengths7374var maxHashLength = [NaN, NaN];7576for (var i = 2; i < 65; i++) {77var maxHash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, i))(new Array(64 + 1).join('1'));78maxHashLength.push(maxHash.length);79} // no operation808182function noop() {} // error checking methods838485function isArrayBuffer(test) {86return Object.prototype.toString.call(test).toLowerCase().indexOf('arraybuffer') > -1;87} // Prepare a Buffer object from the arrayBuffer. Necessary in the browser > node conversion,88// But this function is not useful when running in node directly899091function bufferFromArrayBuffer(arrayBuffer) {92var buffer = Buffer.alloc(arrayBuffer.byteLength);93var view = new Uint8Array(arrayBuffer);9495for (var _i = 0; _i < buffer.length; ++_i) {96buffer[_i] = view[_i];97}9899return buffer;100}101102function loadFromURL(options, cb) {103(0, _request["default"])(options, function (err, response, data) {104if (err) {105return cb(err);106}107108if ('headers' in response && 'location' in response.headers) {109options.url = response.headers.location;110return loadFromURL(options, cb);111}112113if ((0, _typeof2["default"])(data) === 'object' && Buffer.isBuffer(data)) {114return cb(null, data);115}116117var msg = 'Could not load Buffer from <' + options.url + '> ' + '(HTTP: ' + response.statusCode + ')';118return new Error(msg);119});120}121122function loadBufferFromPath(src, cb) {123if (_fs["default"] && typeof _fs["default"].readFile === 'function' && !src.match(/^(http|ftp)s?:\/\/./)) {124_fs["default"].readFile(src, cb);125} else {126loadFromURL({127url: src128}, cb);129}130}131132function isRawRGBAData(obj) {133return obj && (0, _typeof2["default"])(obj) === 'object' && typeof obj.width === 'number' && typeof obj.height === 'number' && (Buffer.isBuffer(obj.data) || obj.data instanceof Uint8Array || typeof Uint8ClampedArray === 'function' && obj.data instanceof Uint8ClampedArray) && (obj.data.length === obj.width * obj.height * 4 || obj.data.length === obj.width * obj.height * 3);134}135136function makeRGBABufferFromRGB(buffer) {137if (buffer.length % 3 !== 0) {138throw new Error('Buffer length is incorrect');139}140141var rgbaBuffer = Buffer.allocUnsafe(buffer.length / 3 * 4);142var j = 0;143144for (var _i2 = 0; _i2 < buffer.length; _i2++) {145rgbaBuffer[j] = buffer[_i2];146147if ((_i2 + 1) % 3 === 0) {148rgbaBuffer[++j] = 255;149}150151j++;152}153154return rgbaBuffer;155}156157var emptyBitmap = {158data: null,159width: null,160height: null161};162/**163* Jimp constructor (from a file)164* @param path a path to the image165* @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap166*/167168/**169* Jimp constructor (from a url with options)170* @param options { url, otherOptions}171* @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap172*/173174/**175* Jimp constructor (from another Jimp image or raw image data)176* @param image a Jimp image to clone177* @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap178*/179180/**181* Jimp constructor (from a Buffer)182* @param data a Buffer containing the image data183* @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap184*/185186/**187* Jimp constructor (to generate a new image)188* @param w the width of the image189* @param h the height of the image190* @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap191*/192193/**194* Jimp constructor (to generate a new image)195* @param w the width of the image196* @param h the height of the image197* @param background color to fill the image with198* @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap199*/200201var Jimp =202/*#__PURE__*/203function (_EventEmitter) {204(0, _inherits2["default"])(Jimp, _EventEmitter);205206// An object representing a bitmap in memory, comprising:207// - data: a buffer of the bitmap data208// - width: the width of the image in pixels209// - height: the height of the image in pixels210// Default colour to use for new pixels211// Default MIME is PNG212// Exif data for the image213// Whether Transparency supporting formats will be exported as RGB or RGBA214function Jimp() {215var _this;216217for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {218args[_key] = arguments[_key];219}220221(0, _classCallCheck2["default"])(this, Jimp);222_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Jimp).call(this));223(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "bitmap", emptyBitmap);224(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_background", 0x00000000);225(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_originalMime", Jimp.MIME_PNG);226(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_exif", null);227(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rgba", true);228(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function (path) {229return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path);230});231(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBase64Async", function (mime) {232return (0, _promisify["default"])(_this.getBase64, (0, _assertThisInitialized2["default"])(_this), mime);233});234(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBuffer", _imageBitmap.getBuffer);235(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBufferAsync", _imageBitmap.getBufferAsync);236(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getPixelColour", _this.getPixelColor);237(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "setPixelColour", _this.setPixelColor);238var jimpInstance = (0, _assertThisInitialized2["default"])(_this);239var cb = noop;240241if (isArrayBuffer(args[0])) {242args[0] = bufferFromArrayBuffer(args[0]);243}244245function finish() {246for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {247args[_key2] = arguments[_key2];248}249250var err = args[0];251var evData = err || {};252evData.methodName = 'constructor';253setTimeout(function () {254var _cb;255256// run on next tick.257if (err && cb === noop) {258jimpInstance.emitError('constructor', err);259} else if (!err) {260jimpInstance.emitMulti('constructor', 'initialized');261}262263(_cb = cb).call.apply(_cb, [jimpInstance].concat(args));264}, 1);265}266267if (typeof args[0] === 'number' && typeof args[1] === 'number' || parseInt(args[0], 10) && parseInt(args[1], 10)) {268// create a new image269var w = parseInt(args[0], 10);270var h = parseInt(args[1], 10);271cb = args[2]; // with a hex color272273if (typeof args[2] === 'number') {274_this._background = args[2];275cb = args[3];276} // with a css color277278279if (typeof args[2] === 'string') {280_this._background = Jimp.cssColorToHex(args[2]);281cb = args[3];282}283284if (typeof cb === 'undefined') {285cb = noop;286}287288if (typeof cb !== 'function') {289return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));290}291292_this.bitmap = {293data: Buffer.alloc(w * h * 4),294width: w,295height: h296};297298for (var _i3 = 0; _i3 < _this.bitmap.data.length; _i3 += 4) {299_this.bitmap.data.writeUInt32BE(_this._background, _i3);300}301302finish(null, (0, _assertThisInitialized2["default"])(_this));303} else if ((0, _typeof2["default"])(args[0]) === 'object' && args[0].url) {304cb = args[1] || noop;305306if (typeof cb !== 'function') {307return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));308}309310loadFromURL(args[0], function (err, data) {311if (err) {312return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);313}314315_this.parseBitmap(data, args[0].url, finish);316});317} else if (args[0] instanceof Jimp) {318// clone an existing Jimp319var original = args[0];320cb = args[1];321322if (typeof cb === 'undefined') {323cb = noop;324}325326if (typeof cb !== 'function') {327return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));328}329330_this.bitmap = {331data: Buffer.from(original.bitmap.data),332width: original.bitmap.width,333height: original.bitmap.height334};335_this._quality = original._quality;336_this._deflateLevel = original._deflateLevel;337_this._deflateStrategy = original._deflateStrategy;338_this._filterType = original._filterType;339_this._rgba = original._rgba;340_this._background = original._background;341_this._originalMime = original._originalMime;342finish(null, (0, _assertThisInitialized2["default"])(_this));343} else if (isRawRGBAData(args[0])) {344var imageData = args[0];345cb = args[1] || noop;346var isRGBA = imageData.width * imageData.height * 4 === imageData.data.length;347var buffer = isRGBA ? Buffer.from(imageData.data) : makeRGBABufferFromRGB(imageData.data);348_this.bitmap = {349data: buffer,350width: imageData.width,351height: imageData.height352};353finish(null, (0, _assertThisInitialized2["default"])(_this));354} else if (typeof args[0] === 'string') {355// read from a path356var path = args[0];357cb = args[1];358359if (typeof cb === 'undefined') {360cb = noop;361}362363if (typeof cb !== 'function') {364return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));365}366367loadBufferFromPath(path, function (err, data) {368if (err) {369return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);370}371372_this.parseBitmap(data, path, finish);373});374} else if ((0, _typeof2["default"])(args[0]) === 'object' && Buffer.isBuffer(args[0])) {375// read from a buffer376var data = args[0];377cb = args[1];378379if (typeof cb !== 'function') {380return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));381}382383_this.parseBitmap(data, null, finish);384} else {385// Allow client libs to add new ways to build a Jimp object.386// Extra constructors must be added by `Jimp.appendConstructorOption()`387cb = args[args.length - 1];388389if (typeof cb !== 'function') {390// TODO: try to solve the args after cb problem.391cb = args[args.length - 2];392393if (typeof cb !== 'function') {394cb = noop;395}396}397398var extraConstructor = Jimp.__extraConstructors.find(function (c) {399return c.test.apply(c, args);400});401402if (extraConstructor) {403new Promise(function (resolve, reject) {404var _extraConstructor$run;405406return (_extraConstructor$run = extraConstructor.run).call.apply(_extraConstructor$run, [(0, _assertThisInitialized2["default"])(_this), resolve, reject].concat(args));407}).then(function () {408return finish(null, (0, _assertThisInitialized2["default"])(_this));409})["catch"](finish);410} else {411return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'No matching constructor overloading was found. ' + 'Please see the docs for how to call the Jimp constructor.', finish));412}413}414415return _this;416}417/**418* Parse a bitmap with the loaded image types.419*420* @param {Buffer} data raw image data421* @param {string} path optional path to file422* @param {function(Error, Jimp)} finish (optional) a callback for when complete423* @memberof Jimp424*/425426427(0, _createClass2["default"])(Jimp, [{428key: "parseBitmap",429value: function parseBitmap(data, path, finish) {430_imageBitmap.parseBitmap.call(this, data, null, finish);431}432/**433* Sets the type of the image (RGB or RGBA) when saving in a format that supports transparency (default is RGBA)434* @param {boolean} bool A Boolean, true to use RGBA or false to use RGB435* @param {function(Error, Jimp)} cb (optional) a callback for when complete436* @returns {Jimp} this for chaining of methods437*/438439}, {440key: "rgba",441value: function rgba(bool, cb) {442if (typeof bool !== 'boolean') {443return _utils.throwError.call(this, 'bool must be a boolean, true for RGBA or false for RGB', cb);444}445446this._rgba = bool;447448if ((0, _utils.isNodePattern)(cb)) {449cb.call(this, null, this);450}451452return this;453}454/**455* Emit for multiple listeners456* @param {string} methodName name of the method to emit an error for457* @param {string} eventName name of the eventName to emit an error for458* @param {object} data to emit459*/460461}, {462key: "emitMulti",463value: function emitMulti(methodName, eventName) {464var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};465data = Object.assign(data, {466methodName: methodName,467eventName: eventName468});469this.emit('any', data);470471if (methodName) {472this.emit(methodName, data);473}474475this.emit(eventName, data);476}477}, {478key: "emitError",479value: function emitError(methodName, err) {480this.emitMulti(methodName, 'error', err);481}482/**483* Get the current height of the image484* @return {number} height of the image485*/486487}, {488key: "getHeight",489value: function getHeight() {490return this.bitmap.height;491}492/**493* Get the current width of the image494* @return {number} width of the image495*/496497}, {498key: "getWidth",499value: function getWidth() {500return this.bitmap.width;501}502/**503* Nicely format Jimp object when sent to the console e.g. console.log(image)504* @returns {string} pretty printed505*/506507}, {508key: "inspect",509value: function inspect() {510return '<Jimp ' + (this.bitmap === emptyBitmap ? 'pending...' : this.bitmap.width + 'x' + this.bitmap.height) + '>';511}512/**513* Nicely format Jimp object when converted to a string514* @returns {string} pretty printed515*/516517}, {518key: "toString",519value: function toString() {520return '[object Jimp]';521}522/**523* Returns the original MIME of the image (default: "image/png")524* @returns {string} the MIME525*/526527}, {528key: "getMIME",529value: function getMIME() {530var mime = this._originalMime || Jimp.MIME_PNG;531return mime;532}533/**534* Returns the appropriate file extension for the original MIME of the image (default: "png")535* @returns {string} the file extension536*/537538}, {539key: "getExtension",540value: function getExtension() {541var mime = this.getMIME();542return MIME.getExtension(mime);543}544/**545* Writes the image to a file546* @param {string} path a path to the destination file547* @param {function(Error, Jimp)} cb (optional) a function to call when the image is saved to disk548* @returns {Jimp} this for chaining of methods549*/550551}, {552key: "write",553value: function write(path, cb) {554var _this2 = this;555556if (!_fs["default"] || !_fs["default"].createWriteStream) {557throw new Error('Cant access the filesystem. You can use the getBase64 method.');558}559560if (typeof path !== 'string') {561return _utils.throwError.call(this, 'path must be a string', cb);562}563564if (typeof cb === 'undefined') {565cb = noop;566}567568if (typeof cb !== 'function') {569return _utils.throwError.call(this, 'cb must be a function', cb);570}571572var mime = MIME.getType(path) || this.getMIME();573574var pathObj = _path["default"].parse(path);575576if (pathObj.dir) {577_mkdirp["default"].sync(pathObj.dir);578}579580this.getBuffer(mime, function (err, buffer) {581if (err) {582return _utils.throwError.call(_this2, err, cb);583}584585var stream = _fs["default"].createWriteStream(path);586587stream.on('open', function () {588stream.write(buffer);589stream.end();590}).on('error', function (err) {591return _utils.throwError.call(_this2, err, cb);592});593stream.on('finish', function () {594cb.call(_this2, null, _this2);595});596});597return this;598}599}, {600key: "getBase64",601602/**603* Converts the image to a base 64 string604* @param {string} mime the mime type of the image data to be created605* @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument606* @returns {Jimp} this for chaining of methods607*/608value: function getBase64(mime, cb) {609if (mime === Jimp.AUTO) {610// allow auto MIME detection611mime = this.getMIME();612}613614if (typeof mime !== 'string') {615return _utils.throwError.call(this, 'mime must be a string', cb);616}617618if (typeof cb !== 'function') {619return _utils.throwError.call(this, 'cb must be a function', cb);620}621622this.getBuffer(mime, function (err, data) {623if (err) {624return _utils.throwError.call(this, err, cb);625}626627var src = 'data:' + mime + ';base64,' + data.toString('base64');628cb.call(this, null, src);629});630return this;631}632}, {633key: "hash",634635/**636* Generates a perceptual hash of the image <https://en.wikipedia.org/wiki/Perceptual_hashing>. And pads the string. Can configure base.637* @param {number} base (optional) a number between 2 and 64 representing the base for the hash (e.g. 2 is binary, 10 is decimal, 16 is hex, 64 is base 64). Defaults to 64.638* @param {function(Error, Jimp)} cb (optional) a callback for when complete639* @returns {string} a string representing the hash640*/641value: function hash(base, cb) {642base = base || 64;643644if (typeof base === 'function') {645cb = base;646base = 64;647}648649if (typeof base !== 'number') {650return _utils.throwError.call(this, 'base must be a number', cb);651}652653if (base < 2 || base > 64) {654return _utils.throwError.call(this, 'base must be a number between 2 and 64', cb);655}656657var hash = this.pHash();658hash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, base))(hash);659660while (hash.length < maxHashLength[base]) {661hash = '0' + hash; // pad out with leading zeros662}663664if ((0, _utils.isNodePattern)(cb)) {665cb.call(this, null, hash);666}667668return hash;669}670/**671* Calculates the perceptual hash672* @returns {number} the perceptual hash673*/674675}, {676key: "pHash",677value: function pHash() {678var pHash = new _phash["default"]();679return pHash.getHash(this);680}681/**682* Calculates the hamming distance of the current image and a hash based on their perceptual hash683* @param {hash} compareHash hash to compare to684* @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical685*/686687}, {688key: "distanceFromHash",689value: function distanceFromHash(compareHash) {690var pHash = new _phash["default"]();691var currentHash = pHash.getHash(this);692return pHash.distance(currentHash, compareHash);693}694/**695* Converts the image to a buffer696* @param {string} mime the mime type of the image buffer to be created697* @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument698* @returns {Jimp} this for chaining of methods699*/700701}, {702key: "getPixelIndex",703704/**705* Returns the offset of a pixel in the bitmap buffer706* @param {number} x the x coordinate707* @param {number} y the y coordinate708* @param {string} edgeHandling (optional) define how to sum pixels from outside the border709* @param {number} cb (optional) a callback for when complete710* @returns {number} the index of the pixel or -1 if not found711*/712value: function getPixelIndex(x, y, edgeHandling, cb) {713var xi;714var yi;715716if (typeof edgeHandling === 'function' && typeof cb === 'undefined') {717cb = edgeHandling;718edgeHandling = null;719}720721if (!edgeHandling) {722edgeHandling = Jimp.EDGE_EXTEND;723}724725if (typeof x !== 'number' || typeof y !== 'number') {726return _utils.throwError.call(this, 'x and y must be numbers', cb);727} // round input728729730x = Math.round(x);731y = Math.round(y);732xi = x;733yi = y;734735if (edgeHandling === Jimp.EDGE_EXTEND) {736if (x < 0) xi = 0;737if (x >= this.bitmap.width) xi = this.bitmap.width - 1;738if (y < 0) yi = 0;739if (y >= this.bitmap.height) yi = this.bitmap.height - 1;740}741742if (edgeHandling === Jimp.EDGE_WRAP) {743if (x < 0) {744xi = this.bitmap.width + x;745}746747if (x >= this.bitmap.width) {748xi = x % this.bitmap.width;749}750751if (y < 0) {752xi = this.bitmap.height + y;753}754755if (y >= this.bitmap.height) {756yi = y % this.bitmap.height;757}758}759760var i = this.bitmap.width * yi + xi << 2; // if out of bounds index is -1761762if (xi < 0 || xi >= this.bitmap.width) {763i = -1;764}765766if (yi < 0 || yi >= this.bitmap.height) {767i = -1;768}769770if ((0, _utils.isNodePattern)(cb)) {771cb.call(this, null, i);772}773774return i;775}776/**777* Returns the hex colour value of a pixel778* @param {number} x the x coordinate779* @param {number} y the y coordinate780* @param {function(Error, Jimp)} cb (optional) a callback for when complete781* @returns {number} the color of the pixel782*/783784}, {785key: "getPixelColor",786value: function getPixelColor(x, y, cb) {787if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb); // round input788789x = Math.round(x);790y = Math.round(y);791var idx = this.getPixelIndex(x, y);792var hex = this.bitmap.data.readUInt32BE(idx);793794if ((0, _utils.isNodePattern)(cb)) {795cb.call(this, null, hex);796}797798return hex;799}800}, {801key: "setPixelColor",802803/**804* Returns the hex colour value of a pixel805* @param {number} hex color to set806* @param {number} x the x coordinate807* @param {number} y the y coordinate808* @param {function(Error, Jimp)} cb (optional) a callback for when complete809* @returns {number} the index of the pixel or -1 if not found810*/811value: function setPixelColor(hex, x, y, cb) {812if (typeof hex !== 'number' || typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'hex, x and y must be numbers', cb); // round input813814x = Math.round(x);815y = Math.round(y);816var idx = this.getPixelIndex(x, y);817this.bitmap.data.writeUInt32BE(hex, idx);818819if ((0, _utils.isNodePattern)(cb)) {820cb.call(this, null, this);821}822823return this;824}825}, {826key: "hasAlpha",827828/**829* Determine if the image contains opaque pixels.830* @return {boolean} hasAlpha whether the image contains opaque pixels831*/832value: function hasAlpha() {833for (var yIndex = 0; yIndex < this.bitmap.height; yIndex++) {834for (var xIndex = 0; xIndex < this.bitmap.width; xIndex++) {835var idx = this.bitmap.width * yIndex + xIndex << 2;836var alpha = this.bitmap.data[idx + 3];837838if (alpha !== 0xff) {839return true;840}841}842}843844return false;845}846/**847* Iterate scan through a region of the bitmap848* @param {number} x the x coordinate to begin the scan at849* @param {number} y the y coordinate to begin the scan at850* @param w the width of the scan region851* @param h the height of the scan region852* @returns {IterableIterator<{x: number, y: number, idx: number, image: Jimp}>}853*/854855}, {856key: "scanIterator",857value: function scanIterator(x, y, w, h) {858if (typeof x !== 'number' || typeof y !== 'number') {859return _utils.throwError.call(this, 'x and y must be numbers');860}861862if (typeof w !== 'number' || typeof h !== 'number') {863return _utils.throwError.call(this, 'w and h must be numbers');864}865866return (0, _utils.scanIterator)(this, x, y, w, h);867}868}]);869return Jimp;870}(_events["default"]);871872function addConstants(constants) {873var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;874Object.entries(constants).forEach(function (_ref) {875var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),876name = _ref2[0],877value = _ref2[1];878879jimpInstance[name] = value;880});881}882883function addJimpMethods(methods) {884var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;885Object.entries(methods).forEach(function (_ref3) {886var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),887name = _ref4[0],888value = _ref4[1];889890jimpInstance.prototype[name] = value;891});892}893894addConstants(constants);895addJimpMethods({896composite: _composite["default"]897});898Jimp.__extraConstructors = [];899/**900* Allow client libs to add new ways to build a Jimp object.901* @param {string} name identify the extra constructor.902* @param {function} test a function that returns true when it accepts the arguments passed to the main constructor.903* @param {function} run where the magic happens.904*/905906Jimp.appendConstructorOption = function (name, test, run) {907Jimp.__extraConstructors.push({908name: name,909test: test,910run: run911});912};913/**914* Read an image from a file or a Buffer. Takes the same args as the constructor915* @returns {Promise} a promise916*/917918919Jimp.read = function () {920for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {921args[_key3] = arguments[_key3];922}923924return new Promise(function (resolve, reject) {925(0, _construct2["default"])(Jimp, args.concat([function (err, image) {926if (err) reject(err);else resolve(image);927}]));928});929};930931Jimp.create = Jimp.read;932/**933* A static helper method that converts RGBA values to a single integer value934* @param {number} r the red value (0-255)935* @param {number} g the green value (0-255)936* @param {number} b the blue value (0-255)937* @param {number} a the alpha value (0-255)938* @param {function(Error, Jimp)} cb (optional) A callback for when complete939* @returns {number} an single integer colour value940*/941942Jimp.rgbaToInt = function (r, g, b, a, cb) {943if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' || typeof a !== 'number') {944return _utils.throwError.call(this, 'r, g, b and a must be numbers', cb);945}946947if (r < 0 || r > 255) {948return _utils.throwError.call(this, 'r must be between 0 and 255', cb);949}950951if (g < 0 || g > 255) {952_utils.throwError.call(this, 'g must be between 0 and 255', cb);953}954955if (b < 0 || b > 255) {956return _utils.throwError.call(this, 'b must be between 0 and 255', cb);957}958959if (a < 0 || a > 255) {960return _utils.throwError.call(this, 'a must be between 0 and 255', cb);961}962963r = Math.round(r);964b = Math.round(b);965g = Math.round(g);966a = Math.round(a);967var i = r * Math.pow(256, 3) + g * Math.pow(256, 2) + b * Math.pow(256, 1) + a * Math.pow(256, 0);968969if ((0, _utils.isNodePattern)(cb)) {970cb.call(this, null, i);971}972973return i;974};975/**976* A static helper method that converts RGBA values to a single integer value977* @param {number} i a single integer value representing an RGBA colour (e.g. 0xFF0000FF for red)978* @param {function(Error, Jimp)} cb (optional) A callback for when complete979* @returns {object} an object with the properties r, g, b and a representing RGBA values980*/981982983Jimp.intToRGBA = function (i, cb) {984if (typeof i !== 'number') {985return _utils.throwError.call(this, 'i must be a number', cb);986}987988var rgba = {};989rgba.r = Math.floor(i / Math.pow(256, 3));990rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));991rgba.b = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) / Math.pow(256, 1));992rgba.a = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2) - rgba.b * Math.pow(256, 1)) / Math.pow(256, 0));993994if ((0, _utils.isNodePattern)(cb)) {995cb.call(this, null, rgba);996}997998return rgba;999};1000/**1001* Converts a css color (Hex, 8-digit (RGBA) Hex, RGB, RGBA, HSL, HSLA, HSV, HSVA, Named) to a hex number1002* @param {string} cssColor a number1003* @returns {number} a hex number representing a color1004*/100510061007Jimp.cssColorToHex = function (cssColor) {1008cssColor = cssColor || 0; // 0, null, undefined, NaN10091010if (typeof cssColor === 'number') return Number(cssColor);1011return parseInt((0, _tinycolor["default"])(cssColor).toHex8(), 16);1012};1013/**1014* Limits a number to between 0 or 2551015* @param {number} n a number1016* @returns {number} the number limited to between 0 or 2551017*/101810191020Jimp.limit255 = function (n) {1021n = Math.max(n, 0);1022n = Math.min(n, 255);1023return n;1024};1025/**1026* Diffs two images and returns1027* @param {Jimp} img1 a Jimp image to compare1028* @param {Jimp} img2 a Jimp image to compare1029* @param {number} threshold (optional) a number, 0 to 1, the smaller the value the more sensitive the comparison (default: 0.1)1030* @returns {object} an object { percent: percent similar, diff: a Jimp image highlighting differences }1031*/103210331034Jimp.diff = function (img1, img2) {1035var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.1;1036if (!(img1 instanceof Jimp) || !(img2 instanceof Jimp)) return _utils.throwError.call(this, 'img1 and img2 must be an Jimp images');1037var bmp1 = img1.bitmap;1038var bmp2 = img2.bitmap;10391040if (bmp1.width !== bmp2.width || bmp1.height !== bmp2.height) {1041if (bmp1.width * bmp1.height > bmp2.width * bmp2.height) {1042// img1 is bigger1043img1 = img1.cloneQuiet().resize(bmp2.width, bmp2.height);1044} else {1045// img2 is bigger (or they are the same in area)1046img2 = img2.cloneQuiet().resize(bmp1.width, bmp1.height);1047}1048}10491050if (typeof threshold !== 'number' || threshold < 0 || threshold > 1) {1051return _utils.throwError.call(this, 'threshold must be a number between 0 and 1');1052}10531054var diff = new Jimp(bmp1.width, bmp1.height, 0xffffffff);1055var numDiffPixels = (0, _pixelmatch["default"])(bmp1.data, bmp2.data, diff.bitmap.data, diff.bitmap.width, diff.bitmap.height, {1056threshold: threshold1057});1058return {1059percent: numDiffPixels / (diff.bitmap.width * diff.bitmap.height),1060image: diff1061};1062};1063/**1064* Calculates the hamming distance of two images based on their perceptual hash1065* @param {Jimp} img1 a Jimp image to compare1066* @param {Jimp} img2 a Jimp image to compare1067* @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical1068*/106910701071Jimp.distance = function (img1, img2) {1072var phash = new _phash["default"]();1073var hash1 = phash.getHash(img1);1074var hash2 = phash.getHash(img2);1075return phash.distance(hash1, hash2);1076};1077/**1078* Calculates the hamming distance of two images based on their perceptual hash1079* @param {hash} hash1 a pHash1080* @param {hash} hash2 a pHash1081* @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical1082*/108310841085Jimp.compareHashes = function (hash1, hash2) {1086var phash = new _phash["default"]();1087return phash.distance(hash1, hash2);1088};1089/**1090* Compute color difference1091* 0 means no difference, 1 means maximum difference.1092* @param {number} rgba1: first color to compare.1093* @param {number} rgba2: second color to compare.1094* Both parameters must be an color object {r:val, g:val, b:val, a:val}1095* Where `a` is optional and `val` is an integer between 0 and 255.1096* @returns {number} float between 0 and 1.1097*/109810991100Jimp.colorDiff = function (rgba1, rgba2) {1101var pow = function pow(n) {1102return Math.pow(n, 2);1103};11041105var max = Math.max;1106var maxVal = 255 * 255 * 3;11071108if (rgba1.a !== 0 && !rgba1.a) {1109rgba1.a = 255;1110}11111112if (rgba2.a !== 0 && !rgba2.a) {1113rgba2.a = 255;1114}11151116return (max(pow(rgba1.r - rgba2.r), pow(rgba1.r - rgba2.r - rgba1.a + rgba2.a)) + max(pow(rgba1.g - rgba2.g), pow(rgba1.g - rgba2.g - rgba1.a + rgba2.a)) + max(pow(rgba1.b - rgba2.b), pow(rgba1.b - rgba2.b - rgba1.a + rgba2.a))) / maxVal;1117};1118/**1119* Helper to create Jimp methods that emit events before and after its execution.1120* @param {string} methodName The name to be appended to Jimp prototype.1121* @param {string} evName The event name to be called.1122* It will be prefixed by `before-` and emitted when on method call.1123* It will be appended by `ed` and emitted after the method run.1124* @param {function} method A function implementing the method itself.1125* It will also create a quiet version that will not emit events, to not1126* mess the user code with many `changed` event calls. You can call with1127* `methodName + "Quiet"`.1128*1129* The emitted event comes with a object parameter to the listener with the1130* `methodName` as one attribute.1131*/113211331134function jimpEvMethod(methodName, evName, method) {1135var evNameBefore = 'before-' + evName;1136var evNameAfter = evName.replace(/e$/, '') + 'ed';11371138Jimp.prototype[methodName] = function () {1139var wrappedCb;11401141for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {1142args[_key4] = arguments[_key4];1143}11441145var cb = args[method.length - 1];1146var jimpInstance = this;11471148if (typeof cb === 'function') {1149wrappedCb = function wrappedCb() {1150for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {1151args[_key5] = arguments[_key5];1152}11531154var err = args[0],1155data = args[1];11561157if (err) {1158jimpInstance.emitError(methodName, err);1159} else {1160jimpInstance.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, data));1161}11621163cb.apply(this, args);1164};11651166args[args.length - 1] = wrappedCb;1167} else {1168wrappedCb = false;1169}11701171this.emitMulti(methodName, evNameBefore);1172var result;11731174try {1175result = method.apply(this, args);11761177if (!wrappedCb) {1178this.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, result));1179}1180} catch (error) {1181error.methodName = methodName;1182this.emitError(methodName, error);1183}11841185return result;1186};11871188Jimp.prototype[methodName + 'Quiet'] = method;1189}1190/**1191* Creates a new image that is a clone of this one.1192* @param {function(Error, Jimp)} cb (optional) A callback for when complete1193* @returns the new image1194*/119511961197jimpEvMethod('clone', 'clone', function (cb) {1198var clone = new Jimp(this);11991200if ((0, _utils.isNodePattern)(cb)) {1201cb.call(clone, null, clone);1202}12031204return clone;1205});1206/**1207* Simplify jimpEvMethod call for the common `change` evName.1208* @param {string} methodName name of the method1209* @param {function} method to watch changes for1210*/12111212function jimpEvChange(methodName, method) {1213jimpEvMethod(methodName, 'change', method);1214}1215/**1216* Sets the type of the image (RGB or RGBA) when saving as PNG format (default is RGBA)1217* @param b A Boolean, true to use RGBA or false to use RGB1218* @param {function(Error, Jimp)} cb (optional) a callback for when complete1219* @returns {Jimp} this for chaining of methods1220*/122112221223jimpEvChange('background', function (hex, cb) {1224if (typeof hex !== 'number') {1225return _utils.throwError.call(this, 'hex must be a hexadecimal rgba value', cb);1226}12271228this._background = hex;12291230if ((0, _utils.isNodePattern)(cb)) {1231cb.call(this, null, this);1232}12331234return this;1235});1236/**1237* Scans through a region of the bitmap, calling a function for each pixel.1238* @param {number} x the x coordinate to begin the scan at1239* @param {number} y the y coordinate to begin the scan at1240* @param w the width of the scan region1241* @param h the height of the scan region1242* @param f a function to call on even pixel; the (x, y) position of the pixel1243* and the index of the pixel in the bitmap buffer are passed to the function1244* @param {function(Error, Jimp)} cb (optional) a callback for when complete1245* @returns {Jimp} this for chaining of methods1246*/12471248jimpEvChange('scan', function (x, y, w, h, f, cb) {1249if (typeof x !== 'number' || typeof y !== 'number') {1250return _utils.throwError.call(this, 'x and y must be numbers', cb);1251}12521253if (typeof w !== 'number' || typeof h !== 'number') {1254return _utils.throwError.call(this, 'w and h must be numbers', cb);1255}12561257if (typeof f !== 'function') {1258return _utils.throwError.call(this, 'f must be a function', cb);1259}12601261var result = (0, _utils.scan)(this, x, y, w, h, f);12621263if ((0, _utils.isNodePattern)(cb)) {1264cb.call(this, null, result);1265}12661267return result;1268});12691270if (process.env.ENVIRONMENT === 'BROWSER') {1271// For use in a web browser or web worker12721273/* global self */1274var gl;12751276if (typeof window !== 'undefined' && (typeof window === "undefined" ? "undefined" : (0, _typeof2["default"])(window)) === 'object') {1277gl = window;1278}12791280if (typeof self !== 'undefined' && (typeof self === "undefined" ? "undefined" : (0, _typeof2["default"])(self)) === 'object') {1281gl = self;1282}12831284gl.Jimp = Jimp;1285gl.Buffer = Buffer;1286}12871288var _default = Jimp;1289exports["default"] = _default;1290//# sourceMappingURL=index.js.map12911292