image-js 0.31.3 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,5 @@
1
1
  # image-js
2
2
 
3
- [![NPM version][npm-image]][npm-url]
4
- [![build status][ci-image]][ci-url]
5
- [![Test coverage][codecov-image]][codecov-url]
6
- [![npm download][download-image]][download-url]
7
-
8
3
  Advanced image processing and manipulation in JavaScript.
9
4
 
10
5
  image-js is a full-featured library that can deal with simple image processing
@@ -12,6 +7,23 @@ image-js is a full-featured library that can deal with simple image processing
12
7
  processing on scientific images (Region of interest (ROI), Hull curve, minimal
13
8
  boundary rectangle (MBR), particle size and orientation, cell imaging, etc.).
14
9
 
10
+ <h3 align="center">
11
+
12
+ <a href="https://www.zakodium.com">
13
+ <img src="https://www.zakodium.com/brand/zakodium-logo-white.svg" width="50" alt="Zakodium logo" />
14
+ </a>
15
+
16
+ <p>
17
+ Maintained by <a href="https://www.zakodium.com">Zakodium</a>
18
+ </p>
19
+
20
+ [![NPM version][npm-image]][npm-url]
21
+ [![build status][ci-image]][ci-url]
22
+ [![Test coverage][codecov-image]][codecov-url]
23
+ [![npm download][download-image]][download-url]
24
+
25
+ </h3>
26
+
15
27
  ## [API Documentation](https://image-js.github.io/image-js/)
16
28
 
17
29
  ## Installation
package/index.d.ts CHANGED
@@ -61,8 +61,9 @@ export declare class Image {
61
61
  // exportMethods
62
62
  save(path: string, options?: SaveOptions): Promise<void>;
63
63
  toDataURL(type?: string, options?: SaveOptions): string;
64
- toBase64(type?: string, options?: SaveOptions): string;
65
- toBlob(type?: string, quality?: number): Blob;
64
+ toBase64(type?: string, options?: SaveOptions): string | Promise<string>;
65
+ toBuffer(options?: SaveOptions): Uint8Array;
66
+ toBlob(type?: string, quality?: number): Promise<Blob>;
66
67
  getCanvas(): HTMLCanvasElement;
67
68
 
68
69
  checkProcessable(processName: string, options: object): void;
@@ -83,8 +84,8 @@ export declare class Image {
83
84
  // divide
84
85
  // hypotenuse
85
86
  // background
86
- // flipX
87
- // flipY
87
+ flipX(): this;
88
+ flipY(): this;
88
89
 
89
90
  blurFilter(options?: { radius?: number }): Image;
90
91
  medianFilter(options?: {
@@ -290,7 +291,7 @@ export interface ResizeOptions {
290
291
  width?: number;
291
292
  height?: number;
292
293
  factor?: number;
293
- interpolation?: InterpolationAlgorithm;
294
+ interpolation?: 'nearestNeighbor';
294
295
  preserveAspectRatio?: boolean;
295
296
  }
296
297
 
@@ -3,11 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.ImageData = exports.DOMImage = void 0;
6
7
  exports.createCanvas = createCanvas;
7
- exports.fetchBinary = fetchBinary;
8
8
  exports.createWriteStream = createWriteStream;
9
+ exports.env = void 0;
10
+ exports.fetchBinary = fetchBinary;
9
11
  exports.writeFile = writeFile;
10
- exports.DOMImage = exports.ImageData = exports.env = void 0;
11
12
  const env = 'browser';
12
13
  exports.env = env;
13
14
  const ImageData = self.ImageData;
@@ -55,7 +55,7 @@ const objectToString = Object.prototype.toString;
55
55
  * 8 and 16 bit depth images.
56
56
  * * position : an array of 2 elements that allows to define a relative position
57
57
  * to a parent image. This will be used in a crop or in the management
58
- * of Region Of Interests (Roi) for exmaple
58
+ * of Region Of Interests (Roi) for example
59
59
  * * data : an array that contains all the points of the image.
60
60
  * Depending the bitDepth Uint8Array (1 bit), Uint8Array (8 bits),
61
61
  * Uint16Array (16 bits), Float32Array (32 bits)
@@ -135,7 +135,7 @@ const objectToString = Object.prototype.toString;
135
135
  * // the RoiManager. A RoiManager will be applied on the original image
136
136
  * // in order to be able to extract from the original image the regions
137
137
  *
138
- * // the result of this console.log result can diretly be pasted
138
+ * // the result of this console.log result can directly be pasted
139
139
  * // in the browser
140
140
  * // console.log(mask.toDataURL());
141
141
  *
@@ -178,6 +178,24 @@ const objectToString = Object.prototype.toString;
178
178
  * var canvas = document.getElementById('myCanvasID');
179
179
  * var image = IJS.fromCanvas(canvas);
180
180
  * </script>
181
+ *
182
+ * @example
183
+ * // Image from matrix of values
184
+ * const [min, max] = d3.extent(temperatures)
185
+ * const colorScaler = d3.scaleSequential([min, max], d3.interpolateRdYlBu);
186
+ *
187
+ * // size = rows * columns * channels
188
+ * const data = new Uint8Array(2*3*3);
189
+ * for (let i = 0; i < temperatures.length; i++) {
190
+ * const {r, g, b} = d3.rgb(colorScaler(temperatures[i]));
191
+ * data[i*3] = r;
192
+ * data[i*3 + 1] = g;
193
+ * data[i*3 + 2] = b;
194
+ * }
195
+ *
196
+ * const image = new Image(2, 3, data, { kind: 'RGB' });
197
+ * // or
198
+ * const image = new Image({ width: 2, height: 3, data, kind: 'RGB'});
181
199
  */
182
200
 
183
201
  class Image {
@@ -8,6 +8,7 @@ exports.default = extendedPoints;
8
8
  /**
9
9
  * Allows to generate an array of points for a binary image (bit depth = 1)
10
10
  * The points consider the beginning and the end of each pixel
11
+ * This method is only used to calculate minimalBoundRectangle
11
12
  * @memberof Image
12
13
  * @instance
13
14
  * @return {Array<Array<number>>} - an array of [x,y] corresponding to the set pixels in the binary image
@@ -35,6 +36,11 @@ function extendedPoints() {
35
36
  pixels.push([x, y + 1]);
36
37
  pixels.push([x + 1, y + 1]);
37
38
  }
39
+ } // this small optimization allows to reduce dramatically the number of points for MBR calculation
40
+
41
+
42
+ while (x < this.width - 2 && this.getBitXY(x + 1, y) === 1 && this.getBitXY(x + 2, y) === 1) {
43
+ x++;
38
44
  }
39
45
  }
40
46
  }
@@ -3,20 +3,21 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.fetchBinary = fetchBinary;
6
+ exports.createCanvas = exports.ImageData = exports.DOMImage = void 0;
7
7
  Object.defineProperty(exports, "createWriteStream", {
8
8
  enumerable: true,
9
9
  get: function () {
10
10
  return _fs.createWriteStream;
11
11
  }
12
12
  });
13
+ exports.env = void 0;
14
+ exports.fetchBinary = fetchBinary;
13
15
  Object.defineProperty(exports, "writeFile", {
14
16
  enumerable: true,
15
17
  get: function () {
16
18
  return _fs.writeFile;
17
19
  }
18
20
  });
19
- exports.DOMImage = exports.ImageData = exports.createCanvas = exports.env = void 0;
20
21
 
21
22
  var _fs = require("fs");
22
23
 
@@ -27,6 +28,7 @@ exports.DOMImage = DOMImage;
27
28
  exports.createCanvas = createCanvas;
28
29
 
29
30
  try {
31
+ // eslint-disable-next-line import/no-unresolved
30
32
  const canvas = require('canvas');
31
33
 
32
34
  exports.createCanvas = createCanvas = canvas.createCanvas;
@@ -3,18 +3,18 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.createPixelArray = createPixelArray;
6
7
  exports.getKind = getKind;
7
- exports.verifyKindDefinition = verifyKindDefinition;
8
8
  exports.getTheoreticalPixelArraySize = getTheoreticalPixelArraySize;
9
- exports.createPixelArray = createPixelArray;
9
+ exports.verifyKindDefinition = verifyKindDefinition;
10
10
 
11
11
  var ColorModel = _interopRequireWildcard(require("../model/model"));
12
12
 
13
13
  var Kind = _interopRequireWildcard(require("./kindNames"));
14
14
 
15
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
15
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
16
 
17
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
18
18
 
19
19
  const kinds = {};
20
20
  kinds[Kind.BINARY] = {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.CMYKA = exports.CMYK = exports.RGBA = exports.RGB = exports.GREYA = exports.GREY = exports.BINARY = void 0;
6
+ exports.RGBA = exports.RGB = exports.GREYA = exports.GREY = exports.CMYKA = exports.CMYK = exports.BINARY = void 0;
7
7
  // Shortcuts for common image kinds
8
8
  const BINARY = 'BINARY';
9
9
  exports.BINARY = BINARY;
@@ -169,9 +169,30 @@ function loadJPEG(data) {
169
169
  useTArray: true,
170
170
  maxMemoryUsageInMB: 1024
171
171
  });
172
- return new _Image.default(jpeg.width, jpeg.height, jpeg.data, {
172
+ let image = new _Image.default(jpeg.width, jpeg.height, jpeg.data, {
173
173
  meta
174
174
  });
175
+
176
+ if (meta && meta.tiff.tags.Orientation) {
177
+ const orientation = meta.tiff.tags.Orientation;
178
+
179
+ if (orientation > 2) {
180
+ image = image.rotate({
181
+ 3: 180,
182
+ 4: 180,
183
+ 5: 90,
184
+ 6: 90,
185
+ 7: 270,
186
+ 8: 270
187
+ }[orientation]);
188
+ }
189
+
190
+ if ([2, 4, 5, 7].includes(orientation)) {
191
+ image = image.flipX();
192
+ }
193
+ }
194
+
195
+ return image;
175
196
  }
176
197
 
177
198
  function loadTIFF(data) {
@@ -7,24 +7,18 @@ exports.default = subtractImage;
7
7
 
8
8
  var _channel = require("../../util/channel");
9
9
 
10
- var _Image = _interopRequireDefault(require("../Image"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
10
  /**
15
11
  * Calculate a new image that is the subtraction between the current image and the otherImage.
16
12
  * @memberof Image
17
13
  * @instance
18
14
  * @param {Image} otherImage
19
15
  * @param {object} [options={}]
20
- * @param {number} [options.bitDepth=this.bitDepth]
21
16
  * @param {number[]|string[]} [options.channels] : to which channel to apply the filter. By default all but alpha.
22
17
  * @param {number[]|string[]} [options.absolute=false] :.take the absolute value of the difference (default minimum=0)
23
18
  * @return {Image}
24
19
  */
25
20
  function subtractImage(otherImage, options = {}) {
26
21
  let {
27
- bitDepth = this.bitDepth,
28
22
  channels,
29
23
  absolute = false
30
24
  } = options;
@@ -44,10 +38,7 @@ function subtractImage(otherImage, options = {}) {
44
38
  throw new Error('subtractImage: both images must have the same number of channels');
45
39
  }
46
40
 
47
- let newImage = _Image.default.createFrom(this, {
48
- bitDepth: bitDepth
49
- });
50
-
41
+ let newImage = this.clone();
51
42
  channels = (0, _channel.validateArrayOfChannels)(this, {
52
43
  channels: channels
53
44
  });
@@ -3,10 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.checkRow = checkRow;
7
- exports.checkColumn = checkColumn;
8
6
  exports.checkChannel = checkChannel;
7
+ exports.checkColumn = checkColumn;
9
8
  exports.checkInterpolation = checkInterpolation;
9
+ exports.checkRow = checkRow;
10
10
  exports.validInterpolations = void 0;
11
11
 
12
12
  function checkRow(image, row) {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.CMYK = exports.HSV = exports.HSL = exports.RGB = exports.GREY = void 0;
6
+ exports.RGB = exports.HSV = exports.HSL = exports.GREY = exports.CMYK = void 0;
7
7
 
8
8
  /**
9
9
  * Color model of an image
@@ -21,9 +21,9 @@ var KindNames = _interopRequireWildcard(require("../core/kindNames"));
21
21
 
22
22
  var _feretDiameters = _interopRequireDefault(require("./feretDiameters"));
23
23
 
24
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
25
 
26
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
27
 
28
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
29
 
@@ -728,7 +728,7 @@ class Roi {
728
728
 
729
729
  get roundness() {
730
730
  /*Slide 24 https://static.horiba.com/fileadmin/Horiba/Products/Scientific/Particle_Characterization/Webinars/Slides/TE011.pdf */
731
- return 4 * this.surface / (Math.PI * this.feretDiameters.max) ** 2;
731
+ return 4 * this.surface / (Math.PI * this.feretDiameters.max ** 2);
732
732
  }
733
733
 
734
734
  get sphericity() {
@@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = renyiEntropy;
7
7
 
8
- var _numSort = require("num-sort");
9
-
10
8
  // see https://github.com/fiji/Auto_Threshold/blob/master/src/main/java/fiji/threshold/Auto_Threshold.java
11
9
  // Kapur J.N., Sahoo P.K., and Wong A.K.C. (1985) "A New Method for
12
10
  // Gray-Level Picture Thresholding Using the Entropy of the Histogram"
@@ -136,7 +134,7 @@ function renyiEntropy(histogram, total) {
136
134
 
137
135
 
138
136
  let tStars = [threshold1, threshold2, threshold3];
139
- tStars.sort(_numSort.ascending);
137
+ tStars.sort((a, b) => a - b);
140
138
  let betas;
141
139
  /* Adjust beta values */
142
140
 
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = getMatrix;
7
7
 
8
- var _mlMatrix = _interopRequireDefault(require("ml-matrix"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
+ var _mlMatrix = require("ml-matrix");
11
9
 
12
10
  /**
13
11
  * @memberof Image
@@ -32,7 +30,7 @@ function getMatrix(options = {}) {
32
30
  channel = 0;
33
31
  }
34
32
 
35
- let matrix = new _mlMatrix.default(this.height, this.width);
33
+ let matrix = new _mlMatrix.Matrix(this.height, this.width);
36
34
 
37
35
  for (let x = 0; x < this.height; x++) {
38
36
  for (let y = 0; y < this.width; y++) {
package/lib/index.js CHANGED
@@ -3,16 +3,17 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "default", {
6
+ Object.defineProperty(exports, "Image", {
7
7
  enumerable: true,
8
8
  get: function () {
9
9
  return _Image.default;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "Image", {
12
+ exports.Kernel = void 0;
13
+ Object.defineProperty(exports, "Shape", {
13
14
  enumerable: true,
14
15
  get: function () {
15
- return _Image.default;
16
+ return _Shape.default;
16
17
  }
17
18
  });
18
19
  Object.defineProperty(exports, "Stack", {
@@ -21,19 +22,19 @@ Object.defineProperty(exports, "Stack", {
21
22
  return _Stack.default;
22
23
  }
23
24
  });
24
- Object.defineProperty(exports, "Shape", {
25
+ exports.Static = void 0;
26
+ Object.defineProperty(exports, "Worker", {
25
27
  enumerable: true,
26
28
  get: function () {
27
- return _Shape.default;
29
+ return _worker.default;
28
30
  }
29
31
  });
30
- Object.defineProperty(exports, "Worker", {
32
+ Object.defineProperty(exports, "default", {
31
33
  enumerable: true,
32
34
  get: function () {
33
- return _worker.default;
35
+ return _Image.default;
34
36
  }
35
37
  });
36
- exports.Kernel = exports.Static = void 0;
37
38
 
38
39
  var _Image = _interopRequireDefault(require("./image/Image"));
39
40
 
@@ -51,9 +52,9 @@ var _Shape = _interopRequireDefault(require("./util/Shape"));
51
52
 
52
53
  var _worker = _interopRequireDefault(require("./worker/worker"));
53
54
 
54
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
55
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
55
56
 
56
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
57
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
57
58
 
58
59
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
59
60
 
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.encode = encode;
7
6
  exports.decode = decode;
7
+ exports.encode = encode;
8
8
  exports.toBase64URL = toBase64URL;
9
9
 
10
10
  /*
@@ -8,9 +8,9 @@ exports.validateChannel = validateChannel;
8
8
 
9
9
  var Model = _interopRequireWildcard(require("../image/model/model"));
10
10
 
11
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
11
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
12
 
13
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
13
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
14
 
15
15
  /**
16
16
  * Specify which channels should be processed
package/lib/util/color.js CHANGED
@@ -4,9 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.css2array = css2array;
7
+ exports.getColors = getColors;
7
8
  exports.getDistinctColors = getDistinctColors;
8
9
  exports.getRandomColor = getRandomColor;
9
- exports.getColors = getColors;
10
10
 
11
11
  var _colorFns = require("@swiftcarrot/color-fns");
12
12
 
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.factorDimensions = factorDimensions;
6
7
  exports.getFactor = getFactor;
7
8
  exports.getThreshold = getThreshold;
8
- exports.factorDimensions = factorDimensions;
9
9
 
10
10
  /**
11
11
  * Converts a factor value to a number between 0 and 1
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.median = median;
7
6
  exports.mean = mean;
7
+ exports.median = median;
8
8
 
9
9
  /**
10
10
  * Returns the median of an histogram
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.SECOND_DERIVATIVE_INV = exports.SECOND_DERIVATIVE = exports.SCHARR_Y = exports.SCHARR_X = exports.SOBEL_Y = exports.SOBEL_X = exports.DISCRETE_LAPLACE_8 = exports.DISCRETE_LAPLACE_4 = void 0;
6
+ exports.SOBEL_Y = exports.SOBEL_X = exports.SECOND_DERIVATIVE_INV = exports.SECOND_DERIVATIVE = exports.SCHARR_Y = exports.SCHARR_X = exports.DISCRETE_LAPLACE_8 = exports.DISCRETE_LAPLACE_4 = void 0;
7
7
  const DISCRETE_LAPLACE_4 = [[0, 1, 0], [1, -4, 1], [0, 1, 0]];
8
8
  exports.DISCRETE_LAPLACE_4 = DISCRETE_LAPLACE_4;
9
9
  const DISCRETE_LAPLACE_8 = [[1, 1, 1], [1, -8, 1], [1, 1, 1]];
@@ -3,17 +3,17 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.round = round;
7
- exports.difference = difference;
8
- exports.normalize = normalize;
9
- exports.rotate = rotate;
10
- exports.dot = dot;
11
6
  exports.angle = angle;
12
7
  exports.boundary = boundary;
13
- exports.perimeter = perimeter;
14
- exports.surface = surface;
8
+ exports.difference = difference;
9
+ exports.dot = dot;
15
10
  exports.minMax = minMax;
16
11
  exports.moveToZeroZero = moveToZeroZero;
12
+ exports.normalize = normalize;
13
+ exports.perimeter = perimeter;
14
+ exports.rotate = rotate;
15
+ exports.round = round;
16
+ exports.surface = surface;
17
17
 
18
18
  /**
19
19
  * Rounds all the x and y values of an array of points
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-js",
3
- "version": "0.31.3",
3
+ "version": "0.33.1",
4
4
  "description": "Image processing and manipulation in JavaScript",
5
5
  "keywords": [
6
6
  "image",
@@ -44,8 +44,10 @@
44
44
  "compile": "npm run clean-lib && cross-env NODE_ENV=npm babel src --out-dir lib --ignore \"**/__tests__\" --quiet",
45
45
  "eslint": "eslint src test/common.js test/nodeScripts --cache",
46
46
  "eslint-fix": "npm run eslint -- --fix",
47
- "prepublishOnly": "npm run compile",
48
- "test": "npm run test-only && npm run eslint",
47
+ "prepack": "npm run compile",
48
+ "prettier": "prettier --check .",
49
+ "prettier-write": "prettier --write .",
50
+ "test": "npm run test-only && npm run eslint && npm run prettier",
49
51
  "test-coverage": "jest --coverage --runInBand",
50
52
  "test-only": "jest"
51
53
  },
@@ -56,33 +58,22 @@
56
58
  "<rootDir>/node_modules/"
57
59
  ]
58
60
  },
59
- "prettier": {
60
- "arrowParens": "always",
61
- "semi": true,
62
- "singleQuote": true,
63
- "tabWidth": 2,
64
- "trailingComma": "all"
65
- },
66
61
  "devDependencies": {
67
- "@babel/cli": "^7.12.10",
68
- "@babel/core": "^7.12.10",
69
- "@babel/plugin-transform-block-scoping": "^7.12.1",
70
- "@babel/plugin-transform-modules-commonjs": "^7.12.1",
71
- "@babel/preset-env": "^7.12.10",
72
- "@babel/register": "^7.12.10",
73
- "@types/jest": "^26.0.19",
74
- "babel-core": "^7.0.0-bridge.0",
75
- "babel-jest": "^26.6.3",
62
+ "@babel/cli": "^7.16.0",
63
+ "@babel/core": "^7.16.0",
64
+ "@babel/plugin-transform-block-scoping": "^7.16.0",
65
+ "@babel/plugin-transform-modules-commonjs": "^7.16.0",
66
+ "@babel/preset-env": "^7.16.0",
67
+ "@types/jest": "^27.0.2",
76
68
  "benchmark": "^2.1.4",
77
- "canvas": "^2.6.1",
78
- "cheminfo-build": "^1.1.8",
69
+ "cheminfo-build": "^1.1.11",
79
70
  "cross-env": "^7.0.3",
80
- "eslint": "^7.15.0",
81
- "eslint-config-cheminfo": "^5.2.2",
71
+ "eslint": "^8.1.0",
72
+ "eslint-config-cheminfo": "^7.1.2",
82
73
  "esm": "^3.2.25",
83
- "jest": "^26.6.3",
84
- "jest-matcher-deep-close-to": "^2.0.1",
85
- "prettier": "^2.2.1",
74
+ "jest": "^27.3.1",
75
+ "jest-matcher-deep-close-to": "^3.0.2",
76
+ "prettier": "^2.4.1",
86
77
  "rimraf": "^3.0.2",
87
78
  "sha.js": "^2.4.11"
88
79
  },
@@ -93,28 +84,27 @@
93
84
  "fast-bmp": "^1.0.0",
94
85
  "fast-jpeg": "^1.0.1",
95
86
  "fast-list": "^1.0.3",
96
- "fast-png": "^5.0.3",
87
+ "fast-png": "^6.1.0",
97
88
  "has-own": "^1.0.1",
98
89
  "image-type": "^4.1.0",
99
90
  "is-array-type": "^1.0.0",
100
91
  "is-integer": "^1.0.7",
101
- "jpeg-js": "^0.4.2",
92
+ "jpeg-js": "^0.4.3",
102
93
  "js-priority-queue": "^0.1.5",
103
94
  "js-quantities": "^1.7.6",
104
95
  "median-quickselect": "^1.0.1",
105
96
  "ml-convolution": "0.2.0",
106
97
  "ml-disjoint-set": "^1.0.0",
107
- "ml-matrix": "^6.5.3",
98
+ "ml-matrix": "^6.8.0",
108
99
  "ml-matrix-convolution": "0.4.3",
109
100
  "ml-regression": "^5.0.0",
110
101
  "monotone-chain-convex-hull": "^1.0.0",
111
102
  "new-array": "^1.0.0",
112
- "num-sort": "^2.1.0",
113
103
  "robust-point-in-polygon": "^1.0.3",
114
- "tiff": "^4.3.0",
104
+ "tiff": "^5.0.2",
115
105
  "web-worker-manager": "^0.2.0"
116
106
  },
117
107
  "engines": {
118
- "node": ">= 10.0.0"
108
+ "node": ">= 12.0.0"
119
109
  }
120
110
  }
@@ -41,7 +41,7 @@ const objectToString = Object.prototype.toString;
41
41
  * 8 and 16 bit depth images.
42
42
  * * position : an array of 2 elements that allows to define a relative position
43
43
  * to a parent image. This will be used in a crop or in the management
44
- * of Region Of Interests (Roi) for exmaple
44
+ * of Region Of Interests (Roi) for example
45
45
  * * data : an array that contains all the points of the image.
46
46
  * Depending the bitDepth Uint8Array (1 bit), Uint8Array (8 bits),
47
47
  * Uint16Array (16 bits), Float32Array (32 bits)
@@ -121,7 +121,7 @@ const objectToString = Object.prototype.toString;
121
121
  * // the RoiManager. A RoiManager will be applied on the original image
122
122
  * // in order to be able to extract from the original image the regions
123
123
  *
124
- * // the result of this console.log result can diretly be pasted
124
+ * // the result of this console.log result can directly be pasted
125
125
  * // in the browser
126
126
  * // console.log(mask.toDataURL());
127
127
  *
@@ -164,6 +164,24 @@ const objectToString = Object.prototype.toString;
164
164
  * var canvas = document.getElementById('myCanvasID');
165
165
  * var image = IJS.fromCanvas(canvas);
166
166
  * </script>
167
+ *
168
+ * @example
169
+ * // Image from matrix of values
170
+ * const [min, max] = d3.extent(temperatures)
171
+ * const colorScaler = d3.scaleSequential([min, max], d3.interpolateRdYlBu);
172
+ *
173
+ * // size = rows * columns * channels
174
+ * const data = new Uint8Array(2*3*3);
175
+ * for (let i = 0; i < temperatures.length; i++) {
176
+ * const {r, g, b} = d3.rgb(colorScaler(temperatures[i]));
177
+ * data[i*3] = r;
178
+ * data[i*3 + 1] = g;
179
+ * data[i*3 + 2] = b;
180
+ * }
181
+ *
182
+ * const image = new Image(2, 3, data, { kind: 'RGB' });
183
+ * // or
184
+ * const image = new Image({ width: 2, height: 3, data, kind: 'RGB'});
167
185
  */
168
186
  export default class Image {
169
187
  constructor(width, height, data, options) {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Allows to generate an array of points for a binary image (bit depth = 1)
3
3
  * The points consider the beginning and the end of each pixel
4
+ * This method is only used to calculate minimalBoundRectangle
4
5
  * @memberof Image
5
6
  * @instance
6
7
  * @return {Array<Array<number>>} - an array of [x,y] corresponding to the set pixels in the binary image
@@ -15,6 +16,7 @@ export default function extendedPoints() {
15
16
  for (let x = 0; x < this.width; x++) {
16
17
  if (this.getBitXY(x, y) === 1) {
17
18
  pixels.push([x, y]);
19
+
18
20
  if (this.getBitXY(x + 1, y) !== 1) {
19
21
  pixels.push([x + 1, y]);
20
22
  pixels.push([x + 1, y + 1]);
@@ -27,6 +29,15 @@ export default function extendedPoints() {
27
29
  pixels.push([x + 1, y + 1]);
28
30
  }
29
31
  }
32
+
33
+ // this small optimization allows to reduce dramatically the number of points for MBR calculation
34
+ while (
35
+ x < this.width - 2 &&
36
+ this.getBitXY(x + 1, y) === 1 &&
37
+ this.getBitXY(x + 2, y) === 1
38
+ ) {
39
+ x++;
40
+ }
30
41
  }
31
42
  }
32
43
  }
@@ -5,6 +5,7 @@ const message =
5
5
 
6
6
  let createCanvas, DOMImage, ImageData;
7
7
  try {
8
+ // eslint-disable-next-line import/no-unresolved
8
9
  const canvas = require('canvas');
9
10
  createCanvas = canvas.createCanvas;
10
11
  DOMImage = canvas.Image;
@@ -137,7 +137,26 @@ function loadJPEG(data) {
137
137
  meta = getMetadata(decodedExif.exif);
138
138
  }
139
139
  const jpeg = decodeJpeg(data, { useTArray: true, maxMemoryUsageInMB: 1024 });
140
- return new Image(jpeg.width, jpeg.height, jpeg.data, { meta });
140
+ let image = new Image(jpeg.width, jpeg.height, jpeg.data, { meta });
141
+ if (meta && meta.tiff.tags.Orientation) {
142
+ const orientation = meta.tiff.tags.Orientation;
143
+ if (orientation > 2) {
144
+ image = image.rotate(
145
+ {
146
+ 3: 180,
147
+ 4: 180,
148
+ 5: 90,
149
+ 6: 90,
150
+ 7: 270,
151
+ 8: 270,
152
+ }[orientation],
153
+ );
154
+ }
155
+ if ([2, 4, 5, 7].includes(orientation)) {
156
+ image = image.flipX();
157
+ }
158
+ }
159
+ return image;
141
160
  }
142
161
 
143
162
  function loadTIFF(data) {
@@ -1,5 +1,4 @@
1
1
  import { validateArrayOfChannels } from '../../util/channel';
2
- import Image from '../Image';
3
2
 
4
3
  /**
5
4
  * Calculate a new image that is the subtraction between the current image and the otherImage.
@@ -7,13 +6,12 @@ import Image from '../Image';
7
6
  * @instance
8
7
  * @param {Image} otherImage
9
8
  * @param {object} [options={}]
10
- * @param {number} [options.bitDepth=this.bitDepth]
11
9
  * @param {number[]|string[]} [options.channels] : to which channel to apply the filter. By default all but alpha.
12
10
  * @param {number[]|string[]} [options.absolute=false] :.take the absolute value of the difference (default minimum=0)
13
11
  * @return {Image}
14
12
  */
15
13
  export default function subtractImage(otherImage, options = {}) {
16
- let { bitDepth = this.bitDepth, channels, absolute = false } = options;
14
+ let { channels, absolute = false } = options;
17
15
  this.checkProcessable('subtractImage', {
18
16
  bitDepth: [8, 16],
19
17
  });
@@ -34,7 +32,7 @@ export default function subtractImage(otherImage, options = {}) {
34
32
  );
35
33
  }
36
34
 
37
- let newImage = Image.createFrom(this, { bitDepth: bitDepth });
35
+ let newImage = this.clone();
38
36
 
39
37
  channels = validateArrayOfChannels(this, { channels: channels });
40
38
 
@@ -705,7 +705,7 @@ export default class Roi {
705
705
 
706
706
  get roundness() {
707
707
  /*Slide 24 https://static.horiba.com/fileadmin/Horiba/Products/Scientific/Particle_Characterization/Webinars/Slides/TE011.pdf */
708
- return (4 * this.surface) / (Math.PI * this.feretDiameters.max) ** 2;
708
+ return (4 * this.surface) / (Math.PI * this.feretDiameters.max ** 2);
709
709
  }
710
710
 
711
711
  get sphericity() {
@@ -5,8 +5,6 @@
5
5
  // M. Emre Celebi
6
6
  // 06.15.2007
7
7
  // Ported to ImageJ plugin by G.Landini from E Celebi's fourier_0.8 routines
8
- import { ascending as sortAsc } from 'num-sort';
9
-
10
8
  export default function renyiEntropy(histogram, total) {
11
9
  let optThreshold; // Optimal threshold
12
10
  let firstBin; // First non-zero bin
@@ -112,7 +110,7 @@ export default function renyiEntropy(histogram, total) {
112
110
  /* End Maximum Entropy Thresholding */
113
111
 
114
112
  let tStars = [threshold1, threshold2, threshold3];
115
- tStars.sort(sortAsc);
113
+ tStars.sort((a, b) => a - b);
116
114
 
117
115
  let betas;
118
116
 
@@ -1,4 +1,4 @@
1
- import Matrix from 'ml-matrix';
1
+ import { Matrix } from 'ml-matrix';
2
2
 
3
3
  /**
4
4
  * @memberof Image
package/CHANGELOG.md DELETED
@@ -1,57 +0,0 @@
1
- # Changelog
2
-
3
- ### [0.31.3](https://www.github.com/image-js/image-js/compare/v0.31.2...v0.31.3) (2020-12-14)
4
-
5
-
6
- ### Bug Fixes
7
-
8
- * update dependencies ([#539](https://www.github.com/image-js/image-js/issues/539)) ([c972f63](https://www.github.com/image-js/image-js/commit/c972f63a181706c65ea144ec1e6a6edf92deba5a))
9
-
10
- ### [0.31.2](https://www.github.com/image-js/image-js/compare/v0.31.1...v0.31.2) (2020-12-10)
11
-
12
-
13
- ### Performance Improvements
14
-
15
- * improve medianFilter ([#537](https://www.github.com/image-js/image-js/issues/537)) ([c341fac](https://www.github.com/image-js/image-js/commit/c341facf65745641510b5c53d1c00e6b3c69697e))
16
-
17
- ### [0.31.1](https://www.github.com/image-js/image-js/compare/v0.31.0...v0.31.1) (2020-11-17)
18
-
19
-
20
- ### Bug Fixes
21
-
22
- * correct hull filled mask ([81a8cd7](https://www.github.com/image-js/image-js/commit/81a8cd713add86fdb46f78024dacc343880d71cd))
23
-
24
- ## [0.31.0](https://www.github.com/image-js/image-js/compare/v0.30.3...v0.31.0) (2020-11-12)
25
-
26
-
27
- ### Features
28
-
29
- * restore old implementations of getMask with hull or mbr ([#532](https://www.github.com/image-js/image-js/issues/532)) ([4d51dbd](https://www.github.com/image-js/image-js/commit/4d51dbd7baffc4cc32d625b2912e4fbdabdf13a0))
30
-
31
- ### [0.30.3](https://www.github.com/image-js/image-js/compare/v0.30.2...v0.30.3) (2020-10-20)
32
-
33
-
34
- ### Bug Fixes
35
-
36
- * **types:** correct return type of Stack.getAverageImage to Image ([#529](https://www.github.com/image-js/image-js/issues/529)) ([ec6588c](https://www.github.com/image-js/image-js/commit/ec6588c2b0152bd865013ffe6fb3e5668c83cae3))
37
-
38
- ### [0.30.2](https://www.github.com/image-js/image-js/compare/v0.30.1...v0.30.2) (2020-10-18)
39
-
40
-
41
- ### Bug Fixes
42
-
43
- * add basic Stack type definition ([#525](https://www.github.com/image-js/image-js/issues/525)) ([d5f1972](https://www.github.com/image-js/image-js/commit/d5f1972fc1f39b506882f46b7c6c7722157bfd4c))
44
-
45
- ### [0.30.1](https://www.github.com/image-js/image-js/compare/v0.30.0...v0.30.1) (2020-10-13)
46
-
47
-
48
- ### Bug Fixes
49
-
50
- * include less files in npm package ([03903a6](https://www.github.com/image-js/image-js/commit/03903a692a3f4801d44d8d017fced52f218d0369))
51
-
52
- ## [0.30.0](https://www.github.com/image-js/image-js/compare/v0.29.0...v0.30.0) (2020-10-13)
53
-
54
-
55
- ### Bug Fixes
56
-
57
- * correct TIFF support in documentation ([7f3993f](https://www.github.com/image-js/image-js/commit/7f3993f189fe8adb32467b9c8522273778392871))