1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291 |
- "use strict";
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.addConstants = addConstants;
- exports.addJimpMethods = addJimpMethods;
- exports.jimpEvMethod = jimpEvMethod;
- exports.jimpEvChange = jimpEvChange;
- Object.defineProperty(exports, "addType", {
- enumerable: true,
- get: function get() {
- return MIME.addType;
- }
- });
- exports["default"] = void 0;
- var _construct2 = _interopRequireDefault(require("@babel/runtime/helpers/construct"));
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
- var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
- var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
- var _fs = _interopRequireDefault(require("fs"));
- var _path = _interopRequireDefault(require("path"));
- var _events = _interopRequireDefault(require("events"));
- var _utils = require("@jimp/utils");
- var _anyBase = _interopRequireDefault(require("any-base"));
- var _mkdirp = _interopRequireDefault(require("mkdirp"));
- var _pixelmatch = _interopRequireDefault(require("pixelmatch"));
- var _tinycolor = _interopRequireDefault(require("tinycolor2"));
- var _phash = _interopRequireDefault(require("./modules/phash"));
- var _request = _interopRequireDefault(require("./request"));
- var _composite = _interopRequireDefault(require("./composite"));
- var _promisify = _interopRequireDefault(require("./utils/promisify"));
- var MIME = _interopRequireWildcard(require("./utils/mime"));
- var _imageBitmap = require("./utils/image-bitmap");
- var constants = _interopRequireWildcard(require("./constants"));
- var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'; // an array storing the maximum string length of hashes at various bases
- // 0 and 1 do not exist as possible hash lengths
- var maxHashLength = [NaN, NaN];
- for (var i = 2; i < 65; i++) {
- var maxHash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, i))(new Array(64 + 1).join('1'));
- maxHashLength.push(maxHash.length);
- } // no operation
- function noop() {} // error checking methods
- function isArrayBuffer(test) {
- return Object.prototype.toString.call(test).toLowerCase().indexOf('arraybuffer') > -1;
- } // Prepare a Buffer object from the arrayBuffer. Necessary in the browser > node conversion,
- // But this function is not useful when running in node directly
- function bufferFromArrayBuffer(arrayBuffer) {
- var buffer = Buffer.alloc(arrayBuffer.byteLength);
- var view = new Uint8Array(arrayBuffer);
- for (var _i = 0; _i < buffer.length; ++_i) {
- buffer[_i] = view[_i];
- }
- return buffer;
- }
- function loadFromURL(options, cb) {
- (0, _request["default"])(options, function (err, response, data) {
- if (err) {
- return cb(err);
- }
- if ('headers' in response && 'location' in response.headers) {
- options.url = response.headers.location;
- return loadFromURL(options, cb);
- }
- if ((0, _typeof2["default"])(data) === 'object' && Buffer.isBuffer(data)) {
- return cb(null, data);
- }
- var msg = 'Could not load Buffer from <' + options.url + '> ' + '(HTTP: ' + response.statusCode + ')';
- return new Error(msg);
- });
- }
- function loadBufferFromPath(src, cb) {
- if (_fs["default"] && typeof _fs["default"].readFile === 'function' && !src.match(/^(http|ftp)s?:\/\/./)) {
- _fs["default"].readFile(src, cb);
- } else {
- loadFromURL({
- url: src
- }, cb);
- }
- }
- function isRawRGBAData(obj) {
- return 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);
- }
- function makeRGBABufferFromRGB(buffer) {
- if (buffer.length % 3 !== 0) {
- throw new Error('Buffer length is incorrect');
- }
- var rgbaBuffer = Buffer.allocUnsafe(buffer.length / 3 * 4);
- var j = 0;
- for (var _i2 = 0; _i2 < buffer.length; _i2++) {
- rgbaBuffer[j] = buffer[_i2];
- if ((_i2 + 1) % 3 === 0) {
- rgbaBuffer[++j] = 255;
- }
- j++;
- }
- return rgbaBuffer;
- }
- var emptyBitmap = {
- data: null,
- width: null,
- height: null
- };
- /**
- * Jimp constructor (from a file)
- * @param path a path to the image
- * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
- */
- /**
- * Jimp constructor (from a url with options)
- * @param options { url, otherOptions}
- * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
- */
- /**
- * Jimp constructor (from another Jimp image or raw image data)
- * @param image a Jimp image to clone
- * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
- */
- /**
- * Jimp constructor (from a Buffer)
- * @param data a Buffer containing the image data
- * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
- */
- /**
- * Jimp constructor (to generate a new image)
- * @param w the width of the image
- * @param h the height of the image
- * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
- */
- /**
- * Jimp constructor (to generate a new image)
- * @param w the width of the image
- * @param h the height of the image
- * @param background color to fill the image with
- * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
- */
- var Jimp =
- /*#__PURE__*/
- function (_EventEmitter) {
- (0, _inherits2["default"])(Jimp, _EventEmitter);
- // An object representing a bitmap in memory, comprising:
- // - data: a buffer of the bitmap data
- // - width: the width of the image in pixels
- // - height: the height of the image in pixels
- // Default colour to use for new pixels
- // Default MIME is PNG
- // Exif data for the image
- // Whether Transparency supporting formats will be exported as RGB or RGBA
- function Jimp() {
- var _this;
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
- (0, _classCallCheck2["default"])(this, Jimp);
- _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Jimp).call(this));
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "bitmap", emptyBitmap);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_background", 0x00000000);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_originalMime", Jimp.MIME_PNG);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_exif", null);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rgba", true);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function (path) {
- return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path);
- });
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBase64Async", function (mime) {
- return (0, _promisify["default"])(_this.getBase64, (0, _assertThisInitialized2["default"])(_this), mime);
- });
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBuffer", _imageBitmap.getBuffer);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBufferAsync", _imageBitmap.getBufferAsync);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getPixelColour", _this.getPixelColor);
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "setPixelColour", _this.setPixelColor);
- var jimpInstance = (0, _assertThisInitialized2["default"])(_this);
- var cb = noop;
- if (isArrayBuffer(args[0])) {
- args[0] = bufferFromArrayBuffer(args[0]);
- }
- function finish() {
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
- var err = args[0];
- var evData = err || {};
- evData.methodName = 'constructor';
- setTimeout(function () {
- var _cb;
- // run on next tick.
- if (err && cb === noop) {
- jimpInstance.emitError('constructor', err);
- } else if (!err) {
- jimpInstance.emitMulti('constructor', 'initialized');
- }
- (_cb = cb).call.apply(_cb, [jimpInstance].concat(args));
- }, 1);
- }
- if (typeof args[0] === 'number' && typeof args[1] === 'number' || parseInt(args[0], 10) && parseInt(args[1], 10)) {
- // create a new image
- var w = parseInt(args[0], 10);
- var h = parseInt(args[1], 10);
- cb = args[2]; // with a hex color
- if (typeof args[2] === 'number') {
- _this._background = args[2];
- cb = args[3];
- } // with a css color
- if (typeof args[2] === 'string') {
- _this._background = Jimp.cssColorToHex(args[2]);
- cb = args[3];
- }
- if (typeof cb === 'undefined') {
- cb = noop;
- }
- if (typeof cb !== 'function') {
- return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
- }
- _this.bitmap = {
- data: Buffer.alloc(w * h * 4),
- width: w,
- height: h
- };
- for (var _i3 = 0; _i3 < _this.bitmap.data.length; _i3 += 4) {
- _this.bitmap.data.writeUInt32BE(_this._background, _i3);
- }
- finish(null, (0, _assertThisInitialized2["default"])(_this));
- } else if ((0, _typeof2["default"])(args[0]) === 'object' && args[0].url) {
- cb = args[1] || noop;
- if (typeof cb !== 'function') {
- return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
- }
- loadFromURL(args[0], function (err, data) {
- if (err) {
- return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
- }
- _this.parseBitmap(data, args[0].url, finish);
- });
- } else if (args[0] instanceof Jimp) {
- // clone an existing Jimp
- var original = args[0];
- cb = args[1];
- if (typeof cb === 'undefined') {
- cb = noop;
- }
- if (typeof cb !== 'function') {
- return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
- }
- _this.bitmap = {
- data: Buffer.from(original.bitmap.data),
- width: original.bitmap.width,
- height: original.bitmap.height
- };
- _this._quality = original._quality;
- _this._deflateLevel = original._deflateLevel;
- _this._deflateStrategy = original._deflateStrategy;
- _this._filterType = original._filterType;
- _this._rgba = original._rgba;
- _this._background = original._background;
- _this._originalMime = original._originalMime;
- finish(null, (0, _assertThisInitialized2["default"])(_this));
- } else if (isRawRGBAData(args[0])) {
- var imageData = args[0];
- cb = args[1] || noop;
- var isRGBA = imageData.width * imageData.height * 4 === imageData.data.length;
- var buffer = isRGBA ? Buffer.from(imageData.data) : makeRGBABufferFromRGB(imageData.data);
- _this.bitmap = {
- data: buffer,
- width: imageData.width,
- height: imageData.height
- };
- finish(null, (0, _assertThisInitialized2["default"])(_this));
- } else if (typeof args[0] === 'string') {
- // read from a path
- var path = args[0];
- cb = args[1];
- if (typeof cb === 'undefined') {
- cb = noop;
- }
- if (typeof cb !== 'function') {
- return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
- }
- loadBufferFromPath(path, function (err, data) {
- if (err) {
- return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
- }
- _this.parseBitmap(data, path, finish);
- });
- } else if ((0, _typeof2["default"])(args[0]) === 'object' && Buffer.isBuffer(args[0])) {
- // read from a buffer
- var data = args[0];
- cb = args[1];
- if (typeof cb !== 'function') {
- return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
- }
- _this.parseBitmap(data, null, finish);
- } else {
- // Allow client libs to add new ways to build a Jimp object.
- // Extra constructors must be added by `Jimp.appendConstructorOption()`
- cb = args[args.length - 1];
- if (typeof cb !== 'function') {
- // TODO: try to solve the args after cb problem.
- cb = args[args.length - 2];
- if (typeof cb !== 'function') {
- cb = noop;
- }
- }
- var extraConstructor = Jimp.__extraConstructors.find(function (c) {
- return c.test.apply(c, args);
- });
- if (extraConstructor) {
- new Promise(function (resolve, reject) {
- var _extraConstructor$run;
- return (_extraConstructor$run = extraConstructor.run).call.apply(_extraConstructor$run, [(0, _assertThisInitialized2["default"])(_this), resolve, reject].concat(args));
- }).then(function () {
- return finish(null, (0, _assertThisInitialized2["default"])(_this));
- })["catch"](finish);
- } else {
- return (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));
- }
- }
- return _this;
- }
- /**
- * Parse a bitmap with the loaded image types.
- *
- * @param {Buffer} data raw image data
- * @param {string} path optional path to file
- * @param {function(Error, Jimp)} finish (optional) a callback for when complete
- * @memberof Jimp
- */
- (0, _createClass2["default"])(Jimp, [{
- key: "parseBitmap",
- value: function parseBitmap(data, path, finish) {
- _imageBitmap.parseBitmap.call(this, data, null, finish);
- }
- /**
- * Sets the type of the image (RGB or RGBA) when saving in a format that supports transparency (default is RGBA)
- * @param {boolean} bool A Boolean, true to use RGBA or false to use RGB
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {Jimp} this for chaining of methods
- */
- }, {
- key: "rgba",
- value: function rgba(bool, cb) {
- if (typeof bool !== 'boolean') {
- return _utils.throwError.call(this, 'bool must be a boolean, true for RGBA or false for RGB', cb);
- }
- this._rgba = bool;
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, this);
- }
- return this;
- }
- /**
- * Emit for multiple listeners
- * @param {string} methodName name of the method to emit an error for
- * @param {string} eventName name of the eventName to emit an error for
- * @param {object} data to emit
- */
- }, {
- key: "emitMulti",
- value: function emitMulti(methodName, eventName) {
- var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- data = Object.assign(data, {
- methodName: methodName,
- eventName: eventName
- });
- this.emit('any', data);
- if (methodName) {
- this.emit(methodName, data);
- }
- this.emit(eventName, data);
- }
- }, {
- key: "emitError",
- value: function emitError(methodName, err) {
- this.emitMulti(methodName, 'error', err);
- }
- /**
- * Get the current height of the image
- * @return {number} height of the image
- */
- }, {
- key: "getHeight",
- value: function getHeight() {
- return this.bitmap.height;
- }
- /**
- * Get the current width of the image
- * @return {number} width of the image
- */
- }, {
- key: "getWidth",
- value: function getWidth() {
- return this.bitmap.width;
- }
- /**
- * Nicely format Jimp object when sent to the console e.g. console.log(image)
- * @returns {string} pretty printed
- */
- }, {
- key: "inspect",
- value: function inspect() {
- return '<Jimp ' + (this.bitmap === emptyBitmap ? 'pending...' : this.bitmap.width + 'x' + this.bitmap.height) + '>';
- }
- /**
- * Nicely format Jimp object when converted to a string
- * @returns {string} pretty printed
- */
- }, {
- key: "toString",
- value: function toString() {
- return '[object Jimp]';
- }
- /**
- * Returns the original MIME of the image (default: "image/png")
- * @returns {string} the MIME
- */
- }, {
- key: "getMIME",
- value: function getMIME() {
- var mime = this._originalMime || Jimp.MIME_PNG;
- return mime;
- }
- /**
- * Returns the appropriate file extension for the original MIME of the image (default: "png")
- * @returns {string} the file extension
- */
- }, {
- key: "getExtension",
- value: function getExtension() {
- var mime = this.getMIME();
- return MIME.getExtension(mime);
- }
- /**
- * Writes the image to a file
- * @param {string} path a path to the destination file
- * @param {function(Error, Jimp)} cb (optional) a function to call when the image is saved to disk
- * @returns {Jimp} this for chaining of methods
- */
- }, {
- key: "write",
- value: function write(path, cb) {
- var _this2 = this;
- if (!_fs["default"] || !_fs["default"].createWriteStream) {
- throw new Error('Cant access the filesystem. You can use the getBase64 method.');
- }
- if (typeof path !== 'string') {
- return _utils.throwError.call(this, 'path must be a string', cb);
- }
- if (typeof cb === 'undefined') {
- cb = noop;
- }
- if (typeof cb !== 'function') {
- return _utils.throwError.call(this, 'cb must be a function', cb);
- }
- var mime = MIME.getType(path) || this.getMIME();
- var pathObj = _path["default"].parse(path);
- if (pathObj.dir) {
- _mkdirp["default"].sync(pathObj.dir);
- }
- this.getBuffer(mime, function (err, buffer) {
- if (err) {
- return _utils.throwError.call(_this2, err, cb);
- }
- var stream = _fs["default"].createWriteStream(path);
- stream.on('open', function () {
- stream.write(buffer);
- stream.end();
- }).on('error', function (err) {
- return _utils.throwError.call(_this2, err, cb);
- });
- stream.on('finish', function () {
- cb.call(_this2, null, _this2);
- });
- });
- return this;
- }
- }, {
- key: "getBase64",
- /**
- * Converts the image to a base 64 string
- * @param {string} mime the mime type of the image data to be created
- * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
- * @returns {Jimp} this for chaining of methods
- */
- value: function getBase64(mime, cb) {
- if (mime === Jimp.AUTO) {
- // allow auto MIME detection
- mime = this.getMIME();
- }
- if (typeof mime !== 'string') {
- return _utils.throwError.call(this, 'mime must be a string', cb);
- }
- if (typeof cb !== 'function') {
- return _utils.throwError.call(this, 'cb must be a function', cb);
- }
- this.getBuffer(mime, function (err, data) {
- if (err) {
- return _utils.throwError.call(this, err, cb);
- }
- var src = 'data:' + mime + ';base64,' + data.toString('base64');
- cb.call(this, null, src);
- });
- return this;
- }
- }, {
- key: "hash",
- /**
- * Generates a perceptual hash of the image <https://en.wikipedia.org/wiki/Perceptual_hashing>. And pads the string. Can configure base.
- * @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.
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {string} a string representing the hash
- */
- value: function hash(base, cb) {
- base = base || 64;
- if (typeof base === 'function') {
- cb = base;
- base = 64;
- }
- if (typeof base !== 'number') {
- return _utils.throwError.call(this, 'base must be a number', cb);
- }
- if (base < 2 || base > 64) {
- return _utils.throwError.call(this, 'base must be a number between 2 and 64', cb);
- }
- var hash = this.pHash();
- hash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, base))(hash);
- while (hash.length < maxHashLength[base]) {
- hash = '0' + hash; // pad out with leading zeros
- }
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, hash);
- }
- return hash;
- }
- /**
- * Calculates the perceptual hash
- * @returns {number} the perceptual hash
- */
- }, {
- key: "pHash",
- value: function pHash() {
- var pHash = new _phash["default"]();
- return pHash.getHash(this);
- }
- /**
- * Calculates the hamming distance of the current image and a hash based on their perceptual hash
- * @param {hash} compareHash hash to compare to
- * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
- */
- }, {
- key: "distanceFromHash",
- value: function distanceFromHash(compareHash) {
- var pHash = new _phash["default"]();
- var currentHash = pHash.getHash(this);
- return pHash.distance(currentHash, compareHash);
- }
- /**
- * Converts the image to a buffer
- * @param {string} mime the mime type of the image buffer to be created
- * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
- * @returns {Jimp} this for chaining of methods
- */
- }, {
- key: "getPixelIndex",
- /**
- * Returns the offset of a pixel in the bitmap buffer
- * @param {number} x the x coordinate
- * @param {number} y the y coordinate
- * @param {string} edgeHandling (optional) define how to sum pixels from outside the border
- * @param {number} cb (optional) a callback for when complete
- * @returns {number} the index of the pixel or -1 if not found
- */
- value: function getPixelIndex(x, y, edgeHandling, cb) {
- var xi;
- var yi;
- if (typeof edgeHandling === 'function' && typeof cb === 'undefined') {
- cb = edgeHandling;
- edgeHandling = null;
- }
- if (!edgeHandling) {
- edgeHandling = Jimp.EDGE_EXTEND;
- }
- if (typeof x !== 'number' || typeof y !== 'number') {
- return _utils.throwError.call(this, 'x and y must be numbers', cb);
- } // round input
- x = Math.round(x);
- y = Math.round(y);
- xi = x;
- yi = y;
- if (edgeHandling === Jimp.EDGE_EXTEND) {
- if (x < 0) xi = 0;
- if (x >= this.bitmap.width) xi = this.bitmap.width - 1;
- if (y < 0) yi = 0;
- if (y >= this.bitmap.height) yi = this.bitmap.height - 1;
- }
- if (edgeHandling === Jimp.EDGE_WRAP) {
- if (x < 0) {
- xi = this.bitmap.width + x;
- }
- if (x >= this.bitmap.width) {
- xi = x % this.bitmap.width;
- }
- if (y < 0) {
- xi = this.bitmap.height + y;
- }
- if (y >= this.bitmap.height) {
- yi = y % this.bitmap.height;
- }
- }
- var i = this.bitmap.width * yi + xi << 2; // if out of bounds index is -1
- if (xi < 0 || xi >= this.bitmap.width) {
- i = -1;
- }
- if (yi < 0 || yi >= this.bitmap.height) {
- i = -1;
- }
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, i);
- }
- return i;
- }
- /**
- * Returns the hex colour value of a pixel
- * @param {number} x the x coordinate
- * @param {number} y the y coordinate
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {number} the color of the pixel
- */
- }, {
- key: "getPixelColor",
- value: function getPixelColor(x, y, cb) {
- if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb); // round input
- x = Math.round(x);
- y = Math.round(y);
- var idx = this.getPixelIndex(x, y);
- var hex = this.bitmap.data.readUInt32BE(idx);
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, hex);
- }
- return hex;
- }
- }, {
- key: "setPixelColor",
- /**
- * Returns the hex colour value of a pixel
- * @param {number} hex color to set
- * @param {number} x the x coordinate
- * @param {number} y the y coordinate
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {number} the index of the pixel or -1 if not found
- */
- value: function setPixelColor(hex, x, y, cb) {
- if (typeof hex !== 'number' || typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'hex, x and y must be numbers', cb); // round input
- x = Math.round(x);
- y = Math.round(y);
- var idx = this.getPixelIndex(x, y);
- this.bitmap.data.writeUInt32BE(hex, idx);
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, this);
- }
- return this;
- }
- }, {
- key: "hasAlpha",
- /**
- * Determine if the image contains opaque pixels.
- * @return {boolean} hasAlpha whether the image contains opaque pixels
- */
- value: function hasAlpha() {
- for (var yIndex = 0; yIndex < this.bitmap.height; yIndex++) {
- for (var xIndex = 0; xIndex < this.bitmap.width; xIndex++) {
- var idx = this.bitmap.width * yIndex + xIndex << 2;
- var alpha = this.bitmap.data[idx + 3];
- if (alpha !== 0xff) {
- return true;
- }
- }
- }
- return false;
- }
- /**
- * Iterate scan through a region of the bitmap
- * @param {number} x the x coordinate to begin the scan at
- * @param {number} y the y coordinate to begin the scan at
- * @param w the width of the scan region
- * @param h the height of the scan region
- * @returns {IterableIterator<{x: number, y: number, idx: number, image: Jimp}>}
- */
- }, {
- key: "scanIterator",
- value: function scanIterator(x, y, w, h) {
- if (typeof x !== 'number' || typeof y !== 'number') {
- return _utils.throwError.call(this, 'x and y must be numbers');
- }
- if (typeof w !== 'number' || typeof h !== 'number') {
- return _utils.throwError.call(this, 'w and h must be numbers');
- }
- return (0, _utils.scanIterator)(this, x, y, w, h);
- }
- }]);
- return Jimp;
- }(_events["default"]);
- function addConstants(constants) {
- var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
- Object.entries(constants).forEach(function (_ref) {
- var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
- name = _ref2[0],
- value = _ref2[1];
- jimpInstance[name] = value;
- });
- }
- function addJimpMethods(methods) {
- var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
- Object.entries(methods).forEach(function (_ref3) {
- var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
- name = _ref4[0],
- value = _ref4[1];
- jimpInstance.prototype[name] = value;
- });
- }
- addConstants(constants);
- addJimpMethods({
- composite: _composite["default"]
- });
- Jimp.__extraConstructors = [];
- /**
- * Allow client libs to add new ways to build a Jimp object.
- * @param {string} name identify the extra constructor.
- * @param {function} test a function that returns true when it accepts the arguments passed to the main constructor.
- * @param {function} run where the magic happens.
- */
- Jimp.appendConstructorOption = function (name, test, run) {
- Jimp.__extraConstructors.push({
- name: name,
- test: test,
- run: run
- });
- };
- /**
- * Read an image from a file or a Buffer. Takes the same args as the constructor
- * @returns {Promise} a promise
- */
- Jimp.read = function () {
- for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
- }
- return new Promise(function (resolve, reject) {
- (0, _construct2["default"])(Jimp, args.concat([function (err, image) {
- if (err) reject(err);else resolve(image);
- }]));
- });
- };
- Jimp.create = Jimp.read;
- /**
- * A static helper method that converts RGBA values to a single integer value
- * @param {number} r the red value (0-255)
- * @param {number} g the green value (0-255)
- * @param {number} b the blue value (0-255)
- * @param {number} a the alpha value (0-255)
- * @param {function(Error, Jimp)} cb (optional) A callback for when complete
- * @returns {number} an single integer colour value
- */
- Jimp.rgbaToInt = function (r, g, b, a, cb) {
- if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' || typeof a !== 'number') {
- return _utils.throwError.call(this, 'r, g, b and a must be numbers', cb);
- }
- if (r < 0 || r > 255) {
- return _utils.throwError.call(this, 'r must be between 0 and 255', cb);
- }
- if (g < 0 || g > 255) {
- _utils.throwError.call(this, 'g must be between 0 and 255', cb);
- }
- if (b < 0 || b > 255) {
- return _utils.throwError.call(this, 'b must be between 0 and 255', cb);
- }
- if (a < 0 || a > 255) {
- return _utils.throwError.call(this, 'a must be between 0 and 255', cb);
- }
- r = Math.round(r);
- b = Math.round(b);
- g = Math.round(g);
- a = Math.round(a);
- var i = r * Math.pow(256, 3) + g * Math.pow(256, 2) + b * Math.pow(256, 1) + a * Math.pow(256, 0);
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, i);
- }
- return i;
- };
- /**
- * A static helper method that converts RGBA values to a single integer value
- * @param {number} i a single integer value representing an RGBA colour (e.g. 0xFF0000FF for red)
- * @param {function(Error, Jimp)} cb (optional) A callback for when complete
- * @returns {object} an object with the properties r, g, b and a representing RGBA values
- */
- Jimp.intToRGBA = function (i, cb) {
- if (typeof i !== 'number') {
- return _utils.throwError.call(this, 'i must be a number', cb);
- }
- var rgba = {};
- rgba.r = Math.floor(i / Math.pow(256, 3));
- rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));
- rgba.b = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) / Math.pow(256, 1));
- rgba.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));
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, rgba);
- }
- return rgba;
- };
- /**
- * Converts a css color (Hex, 8-digit (RGBA) Hex, RGB, RGBA, HSL, HSLA, HSV, HSVA, Named) to a hex number
- * @param {string} cssColor a number
- * @returns {number} a hex number representing a color
- */
- Jimp.cssColorToHex = function (cssColor) {
- cssColor = cssColor || 0; // 0, null, undefined, NaN
- if (typeof cssColor === 'number') return Number(cssColor);
- return parseInt((0, _tinycolor["default"])(cssColor).toHex8(), 16);
- };
- /**
- * Limits a number to between 0 or 255
- * @param {number} n a number
- * @returns {number} the number limited to between 0 or 255
- */
- Jimp.limit255 = function (n) {
- n = Math.max(n, 0);
- n = Math.min(n, 255);
- return n;
- };
- /**
- * Diffs two images and returns
- * @param {Jimp} img1 a Jimp image to compare
- * @param {Jimp} img2 a Jimp image to compare
- * @param {number} threshold (optional) a number, 0 to 1, the smaller the value the more sensitive the comparison (default: 0.1)
- * @returns {object} an object { percent: percent similar, diff: a Jimp image highlighting differences }
- */
- Jimp.diff = function (img1, img2) {
- var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.1;
- if (!(img1 instanceof Jimp) || !(img2 instanceof Jimp)) return _utils.throwError.call(this, 'img1 and img2 must be an Jimp images');
- var bmp1 = img1.bitmap;
- var bmp2 = img2.bitmap;
- if (bmp1.width !== bmp2.width || bmp1.height !== bmp2.height) {
- if (bmp1.width * bmp1.height > bmp2.width * bmp2.height) {
- // img1 is bigger
- img1 = img1.cloneQuiet().resize(bmp2.width, bmp2.height);
- } else {
- // img2 is bigger (or they are the same in area)
- img2 = img2.cloneQuiet().resize(bmp1.width, bmp1.height);
- }
- }
- if (typeof threshold !== 'number' || threshold < 0 || threshold > 1) {
- return _utils.throwError.call(this, 'threshold must be a number between 0 and 1');
- }
- var diff = new Jimp(bmp1.width, bmp1.height, 0xffffffff);
- var numDiffPixels = (0, _pixelmatch["default"])(bmp1.data, bmp2.data, diff.bitmap.data, diff.bitmap.width, diff.bitmap.height, {
- threshold: threshold
- });
- return {
- percent: numDiffPixels / (diff.bitmap.width * diff.bitmap.height),
- image: diff
- };
- };
- /**
- * Calculates the hamming distance of two images based on their perceptual hash
- * @param {Jimp} img1 a Jimp image to compare
- * @param {Jimp} img2 a Jimp image to compare
- * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
- */
- Jimp.distance = function (img1, img2) {
- var phash = new _phash["default"]();
- var hash1 = phash.getHash(img1);
- var hash2 = phash.getHash(img2);
- return phash.distance(hash1, hash2);
- };
- /**
- * Calculates the hamming distance of two images based on their perceptual hash
- * @param {hash} hash1 a pHash
- * @param {hash} hash2 a pHash
- * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
- */
- Jimp.compareHashes = function (hash1, hash2) {
- var phash = new _phash["default"]();
- return phash.distance(hash1, hash2);
- };
- /**
- * Compute color difference
- * 0 means no difference, 1 means maximum difference.
- * @param {number} rgba1: first color to compare.
- * @param {number} rgba2: second color to compare.
- * Both parameters must be an color object {r:val, g:val, b:val, a:val}
- * Where `a` is optional and `val` is an integer between 0 and 255.
- * @returns {number} float between 0 and 1.
- */
- Jimp.colorDiff = function (rgba1, rgba2) {
- var pow = function pow(n) {
- return Math.pow(n, 2);
- };
- var max = Math.max;
- var maxVal = 255 * 255 * 3;
- if (rgba1.a !== 0 && !rgba1.a) {
- rgba1.a = 255;
- }
- if (rgba2.a !== 0 && !rgba2.a) {
- rgba2.a = 255;
- }
- return (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;
- };
- /**
- * Helper to create Jimp methods that emit events before and after its execution.
- * @param {string} methodName The name to be appended to Jimp prototype.
- * @param {string} evName The event name to be called.
- * It will be prefixed by `before-` and emitted when on method call.
- * It will be appended by `ed` and emitted after the method run.
- * @param {function} method A function implementing the method itself.
- * It will also create a quiet version that will not emit events, to not
- * mess the user code with many `changed` event calls. You can call with
- * `methodName + "Quiet"`.
- *
- * The emitted event comes with a object parameter to the listener with the
- * `methodName` as one attribute.
- */
- function jimpEvMethod(methodName, evName, method) {
- var evNameBefore = 'before-' + evName;
- var evNameAfter = evName.replace(/e$/, '') + 'ed';
- Jimp.prototype[methodName] = function () {
- var wrappedCb;
- for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
- args[_key4] = arguments[_key4];
- }
- var cb = args[method.length - 1];
- var jimpInstance = this;
- if (typeof cb === 'function') {
- wrappedCb = function wrappedCb() {
- for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
- args[_key5] = arguments[_key5];
- }
- var err = args[0],
- data = args[1];
- if (err) {
- jimpInstance.emitError(methodName, err);
- } else {
- jimpInstance.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, data));
- }
- cb.apply(this, args);
- };
- args[args.length - 1] = wrappedCb;
- } else {
- wrappedCb = false;
- }
- this.emitMulti(methodName, evNameBefore);
- var result;
- try {
- result = method.apply(this, args);
- if (!wrappedCb) {
- this.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, result));
- }
- } catch (error) {
- error.methodName = methodName;
- this.emitError(methodName, error);
- }
- return result;
- };
- Jimp.prototype[methodName + 'Quiet'] = method;
- }
- /**
- * Creates a new image that is a clone of this one.
- * @param {function(Error, Jimp)} cb (optional) A callback for when complete
- * @returns the new image
- */
- jimpEvMethod('clone', 'clone', function (cb) {
- var clone = new Jimp(this);
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(clone, null, clone);
- }
- return clone;
- });
- /**
- * Simplify jimpEvMethod call for the common `change` evName.
- * @param {string} methodName name of the method
- * @param {function} method to watch changes for
- */
- function jimpEvChange(methodName, method) {
- jimpEvMethod(methodName, 'change', method);
- }
- /**
- * Sets the type of the image (RGB or RGBA) when saving as PNG format (default is RGBA)
- * @param b A Boolean, true to use RGBA or false to use RGB
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {Jimp} this for chaining of methods
- */
- jimpEvChange('background', function (hex, cb) {
- if (typeof hex !== 'number') {
- return _utils.throwError.call(this, 'hex must be a hexadecimal rgba value', cb);
- }
- this._background = hex;
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, this);
- }
- return this;
- });
- /**
- * Scans through a region of the bitmap, calling a function for each pixel.
- * @param {number} x the x coordinate to begin the scan at
- * @param {number} y the y coordinate to begin the scan at
- * @param w the width of the scan region
- * @param h the height of the scan region
- * @param f a function to call on even pixel; the (x, y) position of the pixel
- * and the index of the pixel in the bitmap buffer are passed to the function
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {Jimp} this for chaining of methods
- */
- jimpEvChange('scan', function (x, y, w, h, f, cb) {
- if (typeof x !== 'number' || typeof y !== 'number') {
- return _utils.throwError.call(this, 'x and y must be numbers', cb);
- }
- if (typeof w !== 'number' || typeof h !== 'number') {
- return _utils.throwError.call(this, 'w and h must be numbers', cb);
- }
- if (typeof f !== 'function') {
- return _utils.throwError.call(this, 'f must be a function', cb);
- }
- var result = (0, _utils.scan)(this, x, y, w, h, f);
- if ((0, _utils.isNodePattern)(cb)) {
- cb.call(this, null, result);
- }
- return result;
- });
- if (process.env.ENVIRONMENT === 'BROWSER') {
- // For use in a web browser or web worker
- /* global self */
- var gl;
- if (typeof window !== 'undefined' && (typeof window === "undefined" ? "undefined" : (0, _typeof2["default"])(window)) === 'object') {
- gl = window;
- }
- if (typeof self !== 'undefined' && (typeof self === "undefined" ? "undefined" : (0, _typeof2["default"])(self)) === 'object') {
- gl = self;
- }
- gl.Jimp = Jimp;
- gl.Buffer = Buffer;
- }
- var _default = Jimp;
- exports["default"] = _default;
- //# sourceMappingURL=index.js.map
|