index.js 43 KB

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