index.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.addConstants = addConstants;
  8. exports.addJimpMethods = addJimpMethods;
  9. exports.jimpEvMethod = jimpEvMethod;
  10. exports.jimpEvChange = jimpEvChange;
  11. Object.defineProperty(exports, "addType", {
  12. enumerable: true,
  13. get: function get() {
  14. return MIME.addType;
  15. }
  16. });
  17. exports["default"] = void 0;
  18. var _construct2 = _interopRequireDefault(require("@babel/runtime/helpers/construct"));
  19. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  20. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  21. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  22. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  23. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  24. var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
  25. var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
  26. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  27. var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
  28. var _fs = _interopRequireDefault(require("fs"));
  29. var _path = _interopRequireDefault(require("path"));
  30. var _events = _interopRequireDefault(require("events"));
  31. var _utils = require("@jimp/utils");
  32. var _anyBase = _interopRequireDefault(require("any-base"));
  33. var _mkdirp = _interopRequireDefault(require("mkdirp"));
  34. var _pixelmatch = _interopRequireDefault(require("pixelmatch"));
  35. var _tinycolor = _interopRequireDefault(require("tinycolor2"));
  36. var _phash = _interopRequireDefault(require("./modules/phash"));
  37. var _request = _interopRequireDefault(require("./request"));
  38. var _composite = _interopRequireDefault(require("./composite"));
  39. var _promisify = _interopRequireDefault(require("./utils/promisify"));
  40. var MIME = _interopRequireWildcard(require("./utils/mime"));
  41. var _imageBitmap = require("./utils/image-bitmap");
  42. var constants = _interopRequireWildcard(require("./constants"));
  43. var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'; // an array storing the maximum string length of hashes at various bases
  44. // 0 and 1 do not exist as possible hash lengths
  45. var maxHashLength = [NaN, NaN];
  46. for (var i = 2; i < 65; i++) {
  47. var maxHash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, i))(new Array(64 + 1).join('1'));
  48. maxHashLength.push(maxHash.length);
  49. } // no operation
  50. function noop() {} // error checking methods
  51. function isArrayBuffer(test) {
  52. return Object.prototype.toString.call(test).toLowerCase().indexOf('arraybuffer') > -1;
  53. } // Prepare a Buffer object from the arrayBuffer. Necessary in the browser > node conversion,
  54. // But this function is not useful when running in node directly
  55. function bufferFromArrayBuffer(arrayBuffer) {
  56. var buffer = Buffer.alloc(arrayBuffer.byteLength);
  57. var view = new Uint8Array(arrayBuffer);
  58. for (var _i = 0; _i < buffer.length; ++_i) {
  59. buffer[_i] = view[_i];
  60. }
  61. return buffer;
  62. }
  63. function loadFromURL(options, cb) {
  64. (0, _request["default"])(options, function (err, response, data) {
  65. if (err) {
  66. return cb(err);
  67. }
  68. if ('headers' in response && 'location' in response.headers) {
  69. options.url = response.headers.location;
  70. return loadFromURL(options, cb);
  71. }
  72. if ((0, _typeof2["default"])(data) === 'object' && Buffer.isBuffer(data)) {
  73. return cb(null, data);
  74. }
  75. var msg = 'Could not load Buffer from <' + options.url + '> ' + '(HTTP: ' + response.statusCode + ')';
  76. return new Error(msg);
  77. });
  78. }
  79. function loadBufferFromPath(src, cb) {
  80. if (_fs["default"] && typeof _fs["default"].readFile === 'function' && !src.match(/^(http|ftp)s?:\/\/./)) {
  81. _fs["default"].readFile(src, cb);
  82. } else {
  83. loadFromURL({
  84. url: src
  85. }, cb);
  86. }
  87. }
  88. function isRawRGBAData(obj) {
  89. 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);
  90. }
  91. function makeRGBABufferFromRGB(buffer) {
  92. if (buffer.length % 3 !== 0) {
  93. throw new Error('Buffer length is incorrect');
  94. }
  95. var rgbaBuffer = Buffer.allocUnsafe(buffer.length / 3 * 4);
  96. var j = 0;
  97. for (var _i2 = 0; _i2 < buffer.length; _i2++) {
  98. rgbaBuffer[j] = buffer[_i2];
  99. if ((_i2 + 1) % 3 === 0) {
  100. rgbaBuffer[++j] = 255;
  101. }
  102. j++;
  103. }
  104. return rgbaBuffer;
  105. }
  106. var emptyBitmap = {
  107. data: null,
  108. width: null,
  109. height: null
  110. };
  111. /**
  112. * Jimp constructor (from a file)
  113. * @param path a path to the image
  114. * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
  115. */
  116. /**
  117. * Jimp constructor (from a url with options)
  118. * @param options { url, otherOptions}
  119. * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
  120. */
  121. /**
  122. * Jimp constructor (from another Jimp image or raw image data)
  123. * @param image a Jimp image to clone
  124. * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
  125. */
  126. /**
  127. * Jimp constructor (from a Buffer)
  128. * @param data a Buffer containing the image data
  129. * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
  130. */
  131. /**
  132. * Jimp constructor (to generate a new image)
  133. * @param w the width of the image
  134. * @param h the height of the image
  135. * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
  136. */
  137. /**
  138. * Jimp constructor (to generate a new image)
  139. * @param w the width of the image
  140. * @param h the height of the image
  141. * @param background color to fill the image with
  142. * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
  143. */
  144. var Jimp =
  145. /*#__PURE__*/
  146. function (_EventEmitter) {
  147. (0, _inherits2["default"])(Jimp, _EventEmitter);
  148. // An object representing a bitmap in memory, comprising:
  149. // - data: a buffer of the bitmap data
  150. // - width: the width of the image in pixels
  151. // - height: the height of the image in pixels
  152. // Default colour to use for new pixels
  153. // Default MIME is PNG
  154. // Exif data for the image
  155. // Whether Transparency supporting formats will be exported as RGB or RGBA
  156. function Jimp() {
  157. var _this;
  158. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  159. args[_key] = arguments[_key];
  160. }
  161. (0, _classCallCheck2["default"])(this, Jimp);
  162. _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Jimp).call(this));
  163. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "bitmap", emptyBitmap);
  164. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_background", 0x00000000);
  165. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_originalMime", Jimp.MIME_PNG);
  166. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_exif", null);
  167. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rgba", true);
  168. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function (path) {
  169. return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path);
  170. });
  171. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBase64Async", function (mime) {
  172. return (0, _promisify["default"])(_this.getBase64, (0, _assertThisInitialized2["default"])(_this), mime);
  173. });
  174. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBuffer", _imageBitmap.getBuffer);
  175. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBufferAsync", _imageBitmap.getBufferAsync);
  176. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getPixelColour", _this.getPixelColor);
  177. (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "setPixelColour", _this.setPixelColor);
  178. var jimpInstance = (0, _assertThisInitialized2["default"])(_this);
  179. var cb = noop;
  180. if (isArrayBuffer(args[0])) {
  181. args[0] = bufferFromArrayBuffer(args[0]);
  182. }
  183. function finish() {
  184. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  185. args[_key2] = arguments[_key2];
  186. }
  187. var err = args[0];
  188. var evData = err || {};
  189. evData.methodName = 'constructor';
  190. setTimeout(function () {
  191. var _cb;
  192. // run on next tick.
  193. if (err && cb === noop) {
  194. jimpInstance.emitError('constructor', err);
  195. } else if (!err) {
  196. jimpInstance.emitMulti('constructor', 'initialized');
  197. }
  198. (_cb = cb).call.apply(_cb, [jimpInstance].concat(args));
  199. }, 1);
  200. }
  201. if (typeof args[0] === 'number' && typeof args[1] === 'number' || parseInt(args[0], 10) && parseInt(args[1], 10)) {
  202. // create a new image
  203. var w = parseInt(args[0], 10);
  204. var h = parseInt(args[1], 10);
  205. cb = args[2]; // with a hex color
  206. if (typeof args[2] === 'number') {
  207. _this._background = args[2];
  208. cb = args[3];
  209. } // with a css color
  210. if (typeof args[2] === 'string') {
  211. _this._background = Jimp.cssColorToHex(args[2]);
  212. cb = args[3];
  213. }
  214. if (typeof cb === 'undefined') {
  215. cb = noop;
  216. }
  217. if (typeof cb !== 'function') {
  218. return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
  219. }
  220. _this.bitmap = {
  221. data: Buffer.alloc(w * h * 4),
  222. width: w,
  223. height: h
  224. };
  225. for (var _i3 = 0; _i3 < _this.bitmap.data.length; _i3 += 4) {
  226. _this.bitmap.data.writeUInt32BE(_this._background, _i3);
  227. }
  228. finish(null, (0, _assertThisInitialized2["default"])(_this));
  229. } else if ((0, _typeof2["default"])(args[0]) === 'object' && args[0].url) {
  230. cb = args[1] || noop;
  231. if (typeof cb !== 'function') {
  232. return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
  233. }
  234. loadFromURL(args[0], function (err, data) {
  235. if (err) {
  236. return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
  237. }
  238. _this.parseBitmap(data, args[0].url, finish);
  239. });
  240. } else if (args[0] instanceof Jimp) {
  241. // clone an existing Jimp
  242. var original = args[0];
  243. cb = args[1];
  244. if (typeof cb === 'undefined') {
  245. cb = noop;
  246. }
  247. if (typeof cb !== 'function') {
  248. return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
  249. }
  250. _this.bitmap = {
  251. data: Buffer.from(original.bitmap.data),
  252. width: original.bitmap.width,
  253. height: original.bitmap.height
  254. };
  255. _this._quality = original._quality;
  256. _this._deflateLevel = original._deflateLevel;
  257. _this._deflateStrategy = original._deflateStrategy;
  258. _this._filterType = original._filterType;
  259. _this._rgba = original._rgba;
  260. _this._background = original._background;
  261. _this._originalMime = original._originalMime;
  262. finish(null, (0, _assertThisInitialized2["default"])(_this));
  263. } else if (isRawRGBAData(args[0])) {
  264. var imageData = args[0];
  265. cb = args[1] || noop;
  266. var isRGBA = imageData.width * imageData.height * 4 === imageData.data.length;
  267. var buffer = isRGBA ? Buffer.from(imageData.data) : makeRGBABufferFromRGB(imageData.data);
  268. _this.bitmap = {
  269. data: buffer,
  270. width: imageData.width,
  271. height: imageData.height
  272. };
  273. finish(null, (0, _assertThisInitialized2["default"])(_this));
  274. } else if (typeof args[0] === 'string') {
  275. // read from a path
  276. var path = args[0];
  277. cb = args[1];
  278. if (typeof cb === 'undefined') {
  279. cb = noop;
  280. }
  281. if (typeof cb !== 'function') {
  282. return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
  283. }
  284. loadBufferFromPath(path, function (err, data) {
  285. if (err) {
  286. return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
  287. }
  288. _this.parseBitmap(data, path, finish);
  289. });
  290. } else if ((0, _typeof2["default"])(args[0]) === 'object' && Buffer.isBuffer(args[0])) {
  291. // read from a buffer
  292. var data = args[0];
  293. cb = args[1];
  294. if (typeof cb !== 'function') {
  295. return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
  296. }
  297. _this.parseBitmap(data, null, finish);
  298. } else {
  299. // Allow client libs to add new ways to build a Jimp object.
  300. // Extra constructors must be added by `Jimp.appendConstructorOption()`
  301. cb = args[args.length - 1];
  302. if (typeof cb !== 'function') {
  303. // TODO: try to solve the args after cb problem.
  304. cb = args[args.length - 2];
  305. if (typeof cb !== 'function') {
  306. cb = noop;
  307. }
  308. }
  309. var extraConstructor = Jimp.__extraConstructors.find(function (c) {
  310. return c.test.apply(c, args);
  311. });
  312. if (extraConstructor) {
  313. new Promise(function (resolve, reject) {
  314. var _extraConstructor$run;
  315. return (_extraConstructor$run = extraConstructor.run).call.apply(_extraConstructor$run, [(0, _assertThisInitialized2["default"])(_this), resolve, reject].concat(args));
  316. }).then(function () {
  317. return finish(null, (0, _assertThisInitialized2["default"])(_this));
  318. })["catch"](finish);
  319. } else {
  320. 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));
  321. }
  322. }
  323. return _this;
  324. }
  325. /**
  326. * Parse a bitmap with the loaded image types.
  327. *
  328. * @param {Buffer} data raw image data
  329. * @param {string} path optional path to file
  330. * @param {function(Error, Jimp)} finish (optional) a callback for when complete
  331. * @memberof Jimp
  332. */
  333. (0, _createClass2["default"])(Jimp, [{
  334. key: "parseBitmap",
  335. value: function parseBitmap(data, path, finish) {
  336. _imageBitmap.parseBitmap.call(this, data, null, finish);
  337. }
  338. /**
  339. * Sets the type of the image (RGB or RGBA) when saving in a format that supports transparency (default is RGBA)
  340. * @param {boolean} bool A Boolean, true to use RGBA or false to use RGB
  341. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  342. * @returns {Jimp} this for chaining of methods
  343. */
  344. }, {
  345. key: "rgba",
  346. value: function rgba(bool, cb) {
  347. if (typeof bool !== 'boolean') {
  348. return _utils.throwError.call(this, 'bool must be a boolean, true for RGBA or false for RGB', cb);
  349. }
  350. this._rgba = bool;
  351. if ((0, _utils.isNodePattern)(cb)) {
  352. cb.call(this, null, this);
  353. }
  354. return this;
  355. }
  356. /**
  357. * Emit for multiple listeners
  358. * @param {string} methodName name of the method to emit an error for
  359. * @param {string} eventName name of the eventName to emit an error for
  360. * @param {object} data to emit
  361. */
  362. }, {
  363. key: "emitMulti",
  364. value: function emitMulti(methodName, eventName) {
  365. var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  366. data = Object.assign(data, {
  367. methodName: methodName,
  368. eventName: eventName
  369. });
  370. this.emit('any', data);
  371. if (methodName) {
  372. this.emit(methodName, data);
  373. }
  374. this.emit(eventName, data);
  375. }
  376. }, {
  377. key: "emitError",
  378. value: function emitError(methodName, err) {
  379. this.emitMulti(methodName, 'error', err);
  380. }
  381. /**
  382. * Get the current height of the image
  383. * @return {number} height of the image
  384. */
  385. }, {
  386. key: "getHeight",
  387. value: function getHeight() {
  388. return this.bitmap.height;
  389. }
  390. /**
  391. * Get the current width of the image
  392. * @return {number} width of the image
  393. */
  394. }, {
  395. key: "getWidth",
  396. value: function getWidth() {
  397. return this.bitmap.width;
  398. }
  399. /**
  400. * Nicely format Jimp object when sent to the console e.g. console.log(image)
  401. * @returns {string} pretty printed
  402. */
  403. }, {
  404. key: "inspect",
  405. value: function inspect() {
  406. return '<Jimp ' + (this.bitmap === emptyBitmap ? 'pending...' : this.bitmap.width + 'x' + this.bitmap.height) + '>';
  407. }
  408. /**
  409. * Nicely format Jimp object when converted to a string
  410. * @returns {string} pretty printed
  411. */
  412. }, {
  413. key: "toString",
  414. value: function toString() {
  415. return '[object Jimp]';
  416. }
  417. /**
  418. * Returns the original MIME of the image (default: "image/png")
  419. * @returns {string} the MIME
  420. */
  421. }, {
  422. key: "getMIME",
  423. value: function getMIME() {
  424. var mime = this._originalMime || Jimp.MIME_PNG;
  425. return mime;
  426. }
  427. /**
  428. * Returns the appropriate file extension for the original MIME of the image (default: "png")
  429. * @returns {string} the file extension
  430. */
  431. }, {
  432. key: "getExtension",
  433. value: function getExtension() {
  434. var mime = this.getMIME();
  435. return MIME.getExtension(mime);
  436. }
  437. /**
  438. * Writes the image to a file
  439. * @param {string} path a path to the destination file
  440. * @param {function(Error, Jimp)} cb (optional) a function to call when the image is saved to disk
  441. * @returns {Jimp} this for chaining of methods
  442. */
  443. }, {
  444. key: "write",
  445. value: function write(path, cb) {
  446. var _this2 = this;
  447. if (!_fs["default"] || !_fs["default"].createWriteStream) {
  448. throw new Error('Cant access the filesystem. You can use the getBase64 method.');
  449. }
  450. if (typeof path !== 'string') {
  451. return _utils.throwError.call(this, 'path must be a string', cb);
  452. }
  453. if (typeof cb === 'undefined') {
  454. cb = noop;
  455. }
  456. if (typeof cb !== 'function') {
  457. return _utils.throwError.call(this, 'cb must be a function', cb);
  458. }
  459. var mime = MIME.getType(path) || this.getMIME();
  460. var pathObj = _path["default"].parse(path);
  461. if (pathObj.dir) {
  462. _mkdirp["default"].sync(pathObj.dir);
  463. }
  464. this.getBuffer(mime, function (err, buffer) {
  465. if (err) {
  466. return _utils.throwError.call(_this2, err, cb);
  467. }
  468. var stream = _fs["default"].createWriteStream(path);
  469. stream.on('open', function () {
  470. stream.write(buffer);
  471. stream.end();
  472. }).on('error', function (err) {
  473. return _utils.throwError.call(_this2, err, cb);
  474. });
  475. stream.on('finish', function () {
  476. cb.call(_this2, null, _this2);
  477. });
  478. });
  479. return this;
  480. }
  481. }, {
  482. key: "getBase64",
  483. /**
  484. * Converts the image to a base 64 string
  485. * @param {string} mime the mime type of the image data to be created
  486. * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
  487. * @returns {Jimp} this for chaining of methods
  488. */
  489. value: function getBase64(mime, cb) {
  490. if (mime === Jimp.AUTO) {
  491. // allow auto MIME detection
  492. mime = this.getMIME();
  493. }
  494. if (typeof mime !== 'string') {
  495. return _utils.throwError.call(this, 'mime must be a string', cb);
  496. }
  497. if (typeof cb !== 'function') {
  498. return _utils.throwError.call(this, 'cb must be a function', cb);
  499. }
  500. this.getBuffer(mime, function (err, data) {
  501. if (err) {
  502. return _utils.throwError.call(this, err, cb);
  503. }
  504. var src = 'data:' + mime + ';base64,' + data.toString('base64');
  505. cb.call(this, null, src);
  506. });
  507. return this;
  508. }
  509. }, {
  510. key: "hash",
  511. /**
  512. * Generates a perceptual hash of the image <https://en.wikipedia.org/wiki/Perceptual_hashing>. And pads the string. Can configure base.
  513. * @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.
  514. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  515. * @returns {string} a string representing the hash
  516. */
  517. value: function hash(base, cb) {
  518. base = base || 64;
  519. if (typeof base === 'function') {
  520. cb = base;
  521. base = 64;
  522. }
  523. if (typeof base !== 'number') {
  524. return _utils.throwError.call(this, 'base must be a number', cb);
  525. }
  526. if (base < 2 || base > 64) {
  527. return _utils.throwError.call(this, 'base must be a number between 2 and 64', cb);
  528. }
  529. var hash = this.pHash();
  530. hash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, base))(hash);
  531. while (hash.length < maxHashLength[base]) {
  532. hash = '0' + hash; // pad out with leading zeros
  533. }
  534. if ((0, _utils.isNodePattern)(cb)) {
  535. cb.call(this, null, hash);
  536. }
  537. return hash;
  538. }
  539. /**
  540. * Calculates the perceptual hash
  541. * @returns {number} the perceptual hash
  542. */
  543. }, {
  544. key: "pHash",
  545. value: function pHash() {
  546. var pHash = new _phash["default"]();
  547. return pHash.getHash(this);
  548. }
  549. /**
  550. * Calculates the hamming distance of the current image and a hash based on their perceptual hash
  551. * @param {hash} compareHash hash to compare to
  552. * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
  553. */
  554. }, {
  555. key: "distanceFromHash",
  556. value: function distanceFromHash(compareHash) {
  557. var pHash = new _phash["default"]();
  558. var currentHash = pHash.getHash(this);
  559. return pHash.distance(currentHash, compareHash);
  560. }
  561. /**
  562. * Converts the image to a buffer
  563. * @param {string} mime the mime type of the image buffer to be created
  564. * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
  565. * @returns {Jimp} this for chaining of methods
  566. */
  567. }, {
  568. key: "getPixelIndex",
  569. /**
  570. * Returns the offset of a pixel in the bitmap buffer
  571. * @param {number} x the x coordinate
  572. * @param {number} y the y coordinate
  573. * @param {string} edgeHandling (optional) define how to sum pixels from outside the border
  574. * @param {number} cb (optional) a callback for when complete
  575. * @returns {number} the index of the pixel or -1 if not found
  576. */
  577. value: function getPixelIndex(x, y, edgeHandling, cb) {
  578. var xi;
  579. var yi;
  580. if (typeof edgeHandling === 'function' && typeof cb === 'undefined') {
  581. cb = edgeHandling;
  582. edgeHandling = null;
  583. }
  584. if (!edgeHandling) {
  585. edgeHandling = Jimp.EDGE_EXTEND;
  586. }
  587. if (typeof x !== 'number' || typeof y !== 'number') {
  588. return _utils.throwError.call(this, 'x and y must be numbers', cb);
  589. } // round input
  590. x = Math.round(x);
  591. y = Math.round(y);
  592. xi = x;
  593. yi = y;
  594. if (edgeHandling === Jimp.EDGE_EXTEND) {
  595. if (x < 0) xi = 0;
  596. if (x >= this.bitmap.width) xi = this.bitmap.width - 1;
  597. if (y < 0) yi = 0;
  598. if (y >= this.bitmap.height) yi = this.bitmap.height - 1;
  599. }
  600. if (edgeHandling === Jimp.EDGE_WRAP) {
  601. if (x < 0) {
  602. xi = this.bitmap.width + x;
  603. }
  604. if (x >= this.bitmap.width) {
  605. xi = x % this.bitmap.width;
  606. }
  607. if (y < 0) {
  608. xi = this.bitmap.height + y;
  609. }
  610. if (y >= this.bitmap.height) {
  611. yi = y % this.bitmap.height;
  612. }
  613. }
  614. var i = this.bitmap.width * yi + xi << 2; // if out of bounds index is -1
  615. if (xi < 0 || xi >= this.bitmap.width) {
  616. i = -1;
  617. }
  618. if (yi < 0 || yi >= this.bitmap.height) {
  619. i = -1;
  620. }
  621. if ((0, _utils.isNodePattern)(cb)) {
  622. cb.call(this, null, i);
  623. }
  624. return i;
  625. }
  626. /**
  627. * Returns the hex colour value of a pixel
  628. * @param {number} x the x coordinate
  629. * @param {number} y the y coordinate
  630. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  631. * @returns {number} the color of the pixel
  632. */
  633. }, {
  634. key: "getPixelColor",
  635. value: function getPixelColor(x, y, cb) {
  636. if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb); // round input
  637. x = Math.round(x);
  638. y = Math.round(y);
  639. var idx = this.getPixelIndex(x, y);
  640. var hex = this.bitmap.data.readUInt32BE(idx);
  641. if ((0, _utils.isNodePattern)(cb)) {
  642. cb.call(this, null, hex);
  643. }
  644. return hex;
  645. }
  646. }, {
  647. key: "setPixelColor",
  648. /**
  649. * Returns the hex colour value of a pixel
  650. * @param {number} hex color to set
  651. * @param {number} x the x coordinate
  652. * @param {number} y the y coordinate
  653. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  654. * @returns {number} the index of the pixel or -1 if not found
  655. */
  656. value: function setPixelColor(hex, x, y, cb) {
  657. 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
  658. x = Math.round(x);
  659. y = Math.round(y);
  660. var idx = this.getPixelIndex(x, y);
  661. this.bitmap.data.writeUInt32BE(hex, idx);
  662. if ((0, _utils.isNodePattern)(cb)) {
  663. cb.call(this, null, this);
  664. }
  665. return this;
  666. }
  667. }, {
  668. key: "hasAlpha",
  669. /**
  670. * Determine if the image contains opaque pixels.
  671. * @return {boolean} hasAlpha whether the image contains opaque pixels
  672. */
  673. value: function hasAlpha() {
  674. for (var yIndex = 0; yIndex < this.bitmap.height; yIndex++) {
  675. for (var xIndex = 0; xIndex < this.bitmap.width; xIndex++) {
  676. var idx = this.bitmap.width * yIndex + xIndex << 2;
  677. var alpha = this.bitmap.data[idx + 3];
  678. if (alpha !== 0xff) {
  679. return true;
  680. }
  681. }
  682. }
  683. return false;
  684. }
  685. /**
  686. * Iterate scan through a region of the bitmap
  687. * @param {number} x the x coordinate to begin the scan at
  688. * @param {number} y the y coordinate to begin the scan at
  689. * @param w the width of the scan region
  690. * @param h the height of the scan region
  691. * @returns {IterableIterator<{x: number, y: number, idx: number, image: Jimp}>}
  692. */
  693. }, {
  694. key: "scanIterator",
  695. value: function scanIterator(x, y, w, h) {
  696. if (typeof x !== 'number' || typeof y !== 'number') {
  697. return _utils.throwError.call(this, 'x and y must be numbers');
  698. }
  699. if (typeof w !== 'number' || typeof h !== 'number') {
  700. return _utils.throwError.call(this, 'w and h must be numbers');
  701. }
  702. return (0, _utils.scanIterator)(this, x, y, w, h);
  703. }
  704. }]);
  705. return Jimp;
  706. }(_events["default"]);
  707. function addConstants(constants) {
  708. var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
  709. Object.entries(constants).forEach(function (_ref) {
  710. var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
  711. name = _ref2[0],
  712. value = _ref2[1];
  713. jimpInstance[name] = value;
  714. });
  715. }
  716. function addJimpMethods(methods) {
  717. var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
  718. Object.entries(methods).forEach(function (_ref3) {
  719. var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
  720. name = _ref4[0],
  721. value = _ref4[1];
  722. jimpInstance.prototype[name] = value;
  723. });
  724. }
  725. addConstants(constants);
  726. addJimpMethods({
  727. composite: _composite["default"]
  728. });
  729. Jimp.__extraConstructors = [];
  730. /**
  731. * Allow client libs to add new ways to build a Jimp object.
  732. * @param {string} name identify the extra constructor.
  733. * @param {function} test a function that returns true when it accepts the arguments passed to the main constructor.
  734. * @param {function} run where the magic happens.
  735. */
  736. Jimp.appendConstructorOption = function (name, test, run) {
  737. Jimp.__extraConstructors.push({
  738. name: name,
  739. test: test,
  740. run: run
  741. });
  742. };
  743. /**
  744. * Read an image from a file or a Buffer. Takes the same args as the constructor
  745. * @returns {Promise} a promise
  746. */
  747. Jimp.read = function () {
  748. for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  749. args[_key3] = arguments[_key3];
  750. }
  751. return new Promise(function (resolve, reject) {
  752. (0, _construct2["default"])(Jimp, args.concat([function (err, image) {
  753. if (err) reject(err);else resolve(image);
  754. }]));
  755. });
  756. };
  757. Jimp.create = Jimp.read;
  758. /**
  759. * A static helper method that converts RGBA values to a single integer value
  760. * @param {number} r the red value (0-255)
  761. * @param {number} g the green value (0-255)
  762. * @param {number} b the blue value (0-255)
  763. * @param {number} a the alpha value (0-255)
  764. * @param {function(Error, Jimp)} cb (optional) A callback for when complete
  765. * @returns {number} an single integer colour value
  766. */
  767. Jimp.rgbaToInt = function (r, g, b, a, cb) {
  768. if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' || typeof a !== 'number') {
  769. return _utils.throwError.call(this, 'r, g, b and a must be numbers', cb);
  770. }
  771. if (r < 0 || r > 255) {
  772. return _utils.throwError.call(this, 'r must be between 0 and 255', cb);
  773. }
  774. if (g < 0 || g > 255) {
  775. _utils.throwError.call(this, 'g must be between 0 and 255', cb);
  776. }
  777. if (b < 0 || b > 255) {
  778. return _utils.throwError.call(this, 'b must be between 0 and 255', cb);
  779. }
  780. if (a < 0 || a > 255) {
  781. return _utils.throwError.call(this, 'a must be between 0 and 255', cb);
  782. }
  783. r = Math.round(r);
  784. b = Math.round(b);
  785. g = Math.round(g);
  786. a = Math.round(a);
  787. var i = r * Math.pow(256, 3) + g * Math.pow(256, 2) + b * Math.pow(256, 1) + a * Math.pow(256, 0);
  788. if ((0, _utils.isNodePattern)(cb)) {
  789. cb.call(this, null, i);
  790. }
  791. return i;
  792. };
  793. /**
  794. * A static helper method that converts RGBA values to a single integer value
  795. * @param {number} i a single integer value representing an RGBA colour (e.g. 0xFF0000FF for red)
  796. * @param {function(Error, Jimp)} cb (optional) A callback for when complete
  797. * @returns {object} an object with the properties r, g, b and a representing RGBA values
  798. */
  799. Jimp.intToRGBA = function (i, cb) {
  800. if (typeof i !== 'number') {
  801. return _utils.throwError.call(this, 'i must be a number', cb);
  802. }
  803. var rgba = {};
  804. rgba.r = Math.floor(i / Math.pow(256, 3));
  805. rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));
  806. rgba.b = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) / Math.pow(256, 1));
  807. 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));
  808. if ((0, _utils.isNodePattern)(cb)) {
  809. cb.call(this, null, rgba);
  810. }
  811. return rgba;
  812. };
  813. /**
  814. * Converts a css color (Hex, 8-digit (RGBA) Hex, RGB, RGBA, HSL, HSLA, HSV, HSVA, Named) to a hex number
  815. * @param {string} cssColor a number
  816. * @returns {number} a hex number representing a color
  817. */
  818. Jimp.cssColorToHex = function (cssColor) {
  819. cssColor = cssColor || 0; // 0, null, undefined, NaN
  820. if (typeof cssColor === 'number') return Number(cssColor);
  821. return parseInt((0, _tinycolor["default"])(cssColor).toHex8(), 16);
  822. };
  823. /**
  824. * Limits a number to between 0 or 255
  825. * @param {number} n a number
  826. * @returns {number} the number limited to between 0 or 255
  827. */
  828. Jimp.limit255 = function (n) {
  829. n = Math.max(n, 0);
  830. n = Math.min(n, 255);
  831. return n;
  832. };
  833. /**
  834. * Diffs two images and returns
  835. * @param {Jimp} img1 a Jimp image to compare
  836. * @param {Jimp} img2 a Jimp image to compare
  837. * @param {number} threshold (optional) a number, 0 to 1, the smaller the value the more sensitive the comparison (default: 0.1)
  838. * @returns {object} an object { percent: percent similar, diff: a Jimp image highlighting differences }
  839. */
  840. Jimp.diff = function (img1, img2) {
  841. var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.1;
  842. if (!(img1 instanceof Jimp) || !(img2 instanceof Jimp)) return _utils.throwError.call(this, 'img1 and img2 must be an Jimp images');
  843. var bmp1 = img1.bitmap;
  844. var bmp2 = img2.bitmap;
  845. if (bmp1.width !== bmp2.width || bmp1.height !== bmp2.height) {
  846. if (bmp1.width * bmp1.height > bmp2.width * bmp2.height) {
  847. // img1 is bigger
  848. img1 = img1.cloneQuiet().resize(bmp2.width, bmp2.height);
  849. } else {
  850. // img2 is bigger (or they are the same in area)
  851. img2 = img2.cloneQuiet().resize(bmp1.width, bmp1.height);
  852. }
  853. }
  854. if (typeof threshold !== 'number' || threshold < 0 || threshold > 1) {
  855. return _utils.throwError.call(this, 'threshold must be a number between 0 and 1');
  856. }
  857. var diff = new Jimp(bmp1.width, bmp1.height, 0xffffffff);
  858. var numDiffPixels = (0, _pixelmatch["default"])(bmp1.data, bmp2.data, diff.bitmap.data, diff.bitmap.width, diff.bitmap.height, {
  859. threshold: threshold
  860. });
  861. return {
  862. percent: numDiffPixels / (diff.bitmap.width * diff.bitmap.height),
  863. image: diff
  864. };
  865. };
  866. /**
  867. * Calculates the hamming distance of two images based on their perceptual hash
  868. * @param {Jimp} img1 a Jimp image to compare
  869. * @param {Jimp} img2 a Jimp image to compare
  870. * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
  871. */
  872. Jimp.distance = function (img1, img2) {
  873. var phash = new _phash["default"]();
  874. var hash1 = phash.getHash(img1);
  875. var hash2 = phash.getHash(img2);
  876. return phash.distance(hash1, hash2);
  877. };
  878. /**
  879. * Calculates the hamming distance of two images based on their perceptual hash
  880. * @param {hash} hash1 a pHash
  881. * @param {hash} hash2 a pHash
  882. * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
  883. */
  884. Jimp.compareHashes = function (hash1, hash2) {
  885. var phash = new _phash["default"]();
  886. return phash.distance(hash1, hash2);
  887. };
  888. /**
  889. * Compute color difference
  890. * 0 means no difference, 1 means maximum difference.
  891. * @param {number} rgba1: first color to compare.
  892. * @param {number} rgba2: second color to compare.
  893. * Both parameters must be an color object {r:val, g:val, b:val, a:val}
  894. * Where `a` is optional and `val` is an integer between 0 and 255.
  895. * @returns {number} float between 0 and 1.
  896. */
  897. Jimp.colorDiff = function (rgba1, rgba2) {
  898. var pow = function pow(n) {
  899. return Math.pow(n, 2);
  900. };
  901. var max = Math.max;
  902. var maxVal = 255 * 255 * 3;
  903. if (rgba1.a !== 0 && !rgba1.a) {
  904. rgba1.a = 255;
  905. }
  906. if (rgba2.a !== 0 && !rgba2.a) {
  907. rgba2.a = 255;
  908. }
  909. 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;
  910. };
  911. /**
  912. * Helper to create Jimp methods that emit events before and after its execution.
  913. * @param {string} methodName The name to be appended to Jimp prototype.
  914. * @param {string} evName The event name to be called.
  915. * It will be prefixed by `before-` and emitted when on method call.
  916. * It will be appended by `ed` and emitted after the method run.
  917. * @param {function} method A function implementing the method itself.
  918. * It will also create a quiet version that will not emit events, to not
  919. * mess the user code with many `changed` event calls. You can call with
  920. * `methodName + "Quiet"`.
  921. *
  922. * The emitted event comes with a object parameter to the listener with the
  923. * `methodName` as one attribute.
  924. */
  925. function jimpEvMethod(methodName, evName, method) {
  926. var evNameBefore = 'before-' + evName;
  927. var evNameAfter = evName.replace(/e$/, '') + 'ed';
  928. Jimp.prototype[methodName] = function () {
  929. var wrappedCb;
  930. for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
  931. args[_key4] = arguments[_key4];
  932. }
  933. var cb = args[method.length - 1];
  934. var jimpInstance = this;
  935. if (typeof cb === 'function') {
  936. wrappedCb = function wrappedCb() {
  937. for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
  938. args[_key5] = arguments[_key5];
  939. }
  940. var err = args[0],
  941. data = args[1];
  942. if (err) {
  943. jimpInstance.emitError(methodName, err);
  944. } else {
  945. jimpInstance.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, data));
  946. }
  947. cb.apply(this, args);
  948. };
  949. args[args.length - 1] = wrappedCb;
  950. } else {
  951. wrappedCb = false;
  952. }
  953. this.emitMulti(methodName, evNameBefore);
  954. var result;
  955. try {
  956. result = method.apply(this, args);
  957. if (!wrappedCb) {
  958. this.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, result));
  959. }
  960. } catch (error) {
  961. error.methodName = methodName;
  962. this.emitError(methodName, error);
  963. }
  964. return result;
  965. };
  966. Jimp.prototype[methodName + 'Quiet'] = method;
  967. }
  968. /**
  969. * Creates a new image that is a clone of this one.
  970. * @param {function(Error, Jimp)} cb (optional) A callback for when complete
  971. * @returns the new image
  972. */
  973. jimpEvMethod('clone', 'clone', function (cb) {
  974. var clone = new Jimp(this);
  975. if ((0, _utils.isNodePattern)(cb)) {
  976. cb.call(clone, null, clone);
  977. }
  978. return clone;
  979. });
  980. /**
  981. * Simplify jimpEvMethod call for the common `change` evName.
  982. * @param {string} methodName name of the method
  983. * @param {function} method to watch changes for
  984. */
  985. function jimpEvChange(methodName, method) {
  986. jimpEvMethod(methodName, 'change', method);
  987. }
  988. /**
  989. * Sets the type of the image (RGB or RGBA) when saving as PNG format (default is RGBA)
  990. * @param b A Boolean, true to use RGBA or false to use RGB
  991. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  992. * @returns {Jimp} this for chaining of methods
  993. */
  994. jimpEvChange('background', function (hex, cb) {
  995. if (typeof hex !== 'number') {
  996. return _utils.throwError.call(this, 'hex must be a hexadecimal rgba value', cb);
  997. }
  998. this._background = hex;
  999. if ((0, _utils.isNodePattern)(cb)) {
  1000. cb.call(this, null, this);
  1001. }
  1002. return this;
  1003. });
  1004. /**
  1005. * Scans through a region of the bitmap, calling a function for each pixel.
  1006. * @param {number} x the x coordinate to begin the scan at
  1007. * @param {number} y the y coordinate to begin the scan at
  1008. * @param w the width of the scan region
  1009. * @param h the height of the scan region
  1010. * @param f a function to call on even pixel; the (x, y) position of the pixel
  1011. * and the index of the pixel in the bitmap buffer are passed to the function
  1012. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  1013. * @returns {Jimp} this for chaining of methods
  1014. */
  1015. jimpEvChange('scan', function (x, y, w, h, f, cb) {
  1016. if (typeof x !== 'number' || typeof y !== 'number') {
  1017. return _utils.throwError.call(this, 'x and y must be numbers', cb);
  1018. }
  1019. if (typeof w !== 'number' || typeof h !== 'number') {
  1020. return _utils.throwError.call(this, 'w and h must be numbers', cb);
  1021. }
  1022. if (typeof f !== 'function') {
  1023. return _utils.throwError.call(this, 'f must be a function', cb);
  1024. }
  1025. var result = (0, _utils.scan)(this, x, y, w, h, f);
  1026. if ((0, _utils.isNodePattern)(cb)) {
  1027. cb.call(this, null, result);
  1028. }
  1029. return result;
  1030. });
  1031. if (process.env.ENVIRONMENT === 'BROWSER') {
  1032. // For use in a web browser or web worker
  1033. /* global self */
  1034. var gl;
  1035. if (typeof window !== 'undefined' && (typeof window === "undefined" ? "undefined" : (0, _typeof2["default"])(window)) === 'object') {
  1036. gl = window;
  1037. }
  1038. if (typeof self !== 'undefined' && (typeof self === "undefined" ? "undefined" : (0, _typeof2["default"])(self)) === 'object') {
  1039. gl = self;
  1040. }
  1041. gl.Jimp = Jimp;
  1042. gl.Buffer = Buffer;
  1043. }
  1044. var _default = Jimp;
  1045. exports["default"] = _default;
  1046. //# sourceMappingURL=index.js.map