image-js 0.35.1 → 0.35.3
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/index.d.ts +99 -35
- package/lib/browser/environment.js +0 -6
- package/lib/browser/worker/extend.js +0 -3
- package/lib/browser/worker/process/background.js +0 -12
- package/lib/browser/worker/worker.js +0 -17
- package/lib/image/Image.js +18 -51
- package/lib/image/compute/colorHistogram.js +0 -8
- package/lib/image/compute/countAlphaPixels.js +0 -3
- package/lib/image/compute/extendedPoints.js +2 -7
- package/lib/image/compute/histogram.js +6 -25
- package/lib/image/compute/localMaxima.js +2 -10
- package/lib/image/compute/max.js +0 -5
- package/lib/image/compute/mean.js +0 -4
- package/lib/image/compute/median.js +0 -4
- package/lib/image/compute/min.js +0 -5
- package/lib/image/compute/minimalBoundingRectangle.js +5 -18
- package/lib/image/compute/moment.js +0 -3
- package/lib/image/compute/monotoneChainConvexHull.js +0 -3
- package/lib/image/compute/points.js +0 -3
- package/lib/image/compute/relativePosition.js +2 -8
- package/lib/image/compute/sum.js +0 -5
- package/lib/image/core/bitMethods.js +0 -11
- package/lib/image/core/checkProcessable.js +0 -13
- package/lib/image/core/environment.js +0 -8
- package/lib/image/core/export.js +0 -38
- package/lib/image/core/extend.js +0 -13
- package/lib/image/core/getRGBAData.js +0 -15
- package/lib/image/core/kind.js +4 -28
- package/lib/image/core/kindNames.js +1 -0
- package/lib/image/core/load.js +1 -53
- package/lib/image/core/mediaTypes.js +0 -2
- package/lib/image/core/valueMethods.js +0 -13
- package/lib/image/extend.js +7 -83
- package/lib/image/filter/abs.js +0 -3
- package/lib/image/filter/add.js +2 -8
- package/lib/image/filter/background.js +0 -9
- package/lib/image/filter/blurFilter.js +0 -6
- package/lib/image/filter/divide.js +0 -8
- package/lib/image/filter/flipX.js +0 -5
- package/lib/image/filter/flipY.js +0 -4
- package/lib/image/filter/gaussianFilter.js +0 -5
- package/lib/image/filter/gradientFilter.js +0 -10
- package/lib/image/filter/hypotenuse.js +0 -13
- package/lib/image/filter/invert.js +0 -9
- package/lib/image/filter/level.js +1 -19
- package/lib/image/filter/medianFilter.js +0 -15
- package/lib/image/filter/multiply.js +0 -10
- package/lib/image/filter/scharrFilter.js +0 -4
- package/lib/image/filter/sobelFilter.js +0 -4
- package/lib/image/filter/subtract.js +0 -8
- package/lib/image/filter/subtractImage.js +0 -10
- package/lib/image/internal/checks.js +1 -9
- package/lib/image/internal/clamp.js +0 -1
- package/lib/image/internal/copy.js +0 -2
- package/lib/image/internal/copyAlphaChannel.js +0 -1
- package/lib/image/internal/getImageParameters.js +0 -1
- package/lib/image/internal/getOutputImage.js +1 -13
- package/lib/image/model/model.js +1 -1
- package/lib/image/morphology/blackHat.js +0 -5
- package/lib/image/morphology/close.js +0 -5
- package/lib/image/morphology/dilate.js +0 -40
- package/lib/image/morphology/erode.js +0 -40
- package/lib/image/morphology/morphologicalGradient.js +0 -5
- package/lib/image/morphology/open.js +0 -5
- package/lib/image/morphology/topHat.js +0 -5
- package/lib/image/operator/cannyEdge.js +0 -3
- package/lib/image/operator/convolution.js +9 -34
- package/lib/image/operator/convolutionSeparable.js +0 -10
- package/lib/image/operator/extract.js +4 -13
- package/lib/image/operator/floodFill.js +2 -15
- package/lib/image/operator/getSeparatedKernel.js +0 -2
- package/lib/image/operator/paintLabels.js +8 -19
- package/lib/image/operator/paintMasks.js +2 -12
- package/lib/image/operator/paintPoints.js +0 -9
- package/lib/image/operator/paintPolygon.js +1 -15
- package/lib/image/operator/paintPolygons.js +2 -6
- package/lib/image/operator/paintPolyline.js +0 -7
- package/lib/image/operator/paintPolylines.js +1 -5
- package/lib/image/roi/Roi.js +27 -207
- package/lib/image/roi/RoiLayer.js +1 -22
- package/lib/image/roi/RoiMap.js +5 -38
- package/lib/image/roi/creator/fromMask.js +4 -22
- package/lib/image/roi/creator/fromMaskConnectedComponentLabelingAlgorithm.js +2 -20
- package/lib/image/roi/creator/fromMaxima.js +10 -43
- package/lib/image/roi/creator/fromPoints.js +2 -10
- package/lib/image/roi/creator/fromWaterShed.js +6 -17
- package/lib/image/roi/feretDiameters.js +9 -21
- package/lib/image/roi/manager.js +30 -119
- package/lib/image/roi/util/commonBorderLength.js +5 -16
- package/lib/image/roi/util/mergeRoi.js +2 -21
- package/lib/image/transform/cmyk.js +0 -9
- package/lib/image/transform/colorDepth.js +0 -12
- package/lib/image/transform/crop.js +0 -20
- package/lib/image/transform/cropAlpha.js +0 -11
- package/lib/image/transform/grey.js +0 -16
- package/lib/image/transform/greyAlgorithms.js +1 -24
- package/lib/image/transform/hsl.js +0 -16
- package/lib/image/transform/hsv.js +0 -15
- package/lib/image/transform/insert.js +0 -6
- package/lib/image/transform/mask/huang.js +3 -18
- package/lib/image/transform/mask/intermodes.js +3 -14
- package/lib/image/transform/mask/isodata.js +0 -14
- package/lib/image/transform/mask/li.js +12 -42
- package/lib/image/transform/mask/mask.js +1 -13
- package/lib/image/transform/mask/maxEntropy.js +8 -25
- package/lib/image/transform/mask/mean.js +1 -3
- package/lib/image/transform/mask/minError.js +10 -21
- package/lib/image/transform/mask/minimum.js +0 -20
- package/lib/image/transform/mask/moments.js +4 -17
- package/lib/image/transform/mask/otsu.js +1 -7
- package/lib/image/transform/mask/percentile.js +0 -8
- package/lib/image/transform/mask/renyiEntropy.js +8 -34
- package/lib/image/transform/mask/shanbhag.js +8 -25
- package/lib/image/transform/mask/thresholdAlgorithms.js +1 -17
- package/lib/image/transform/mask/triangle.js +13 -29
- package/lib/image/transform/mask/yen.js +2 -14
- package/lib/image/transform/pad.js +0 -20
- package/lib/image/transform/resize/nearestNeighbor.js +0 -6
- package/lib/image/transform/resize/resize.js +0 -16
- package/lib/image/transform/rgba.js +0 -9
- package/lib/image/transform/rgba8.js +0 -3
- package/lib/image/transform/rotate.js +0 -29
- package/lib/image/transform/rotateFree.js +0 -31
- package/lib/image/transform/warping.js +2 -35
- package/lib/image/utility/combineChannels.js +0 -11
- package/lib/image/utility/getBestMatch.js +2 -13
- package/lib/image/utility/getChannel.js +0 -10
- package/lib/image/utility/getClosestCommonParent.js +6 -23
- package/lib/image/utility/getColumn.js +0 -4
- package/lib/image/utility/getIntersection.js +2 -18
- package/lib/image/utility/getMatrix.js +0 -7
- package/lib/image/utility/getPixelsArray.js +0 -5
- package/lib/image/utility/getPixelsGrid.js +0 -11
- package/lib/image/utility/getRow.js +0 -4
- package/lib/image/utility/getSimilarity.js +3 -17
- package/lib/image/utility/getThreshold.js +0 -4
- package/lib/image/utility/setBorder.js +0 -16
- package/lib/image/utility/setChannel.js +0 -6
- package/lib/image/utility/setMatrix.js +0 -6
- package/lib/image/utility/split.js +2 -15
- package/lib/index.js +0 -12
- package/lib/kernel/kernel.js +0 -3
- package/lib/kernel/laplacianOfGaussian.js +1 -7
- package/lib/node_modules/test/binary.js +0 -3
- package/lib/node_modules/test/oneRoi.js +0 -2
- package/lib/stack/Stack.js +2 -35
- package/lib/stack/compute/histogram.js +0 -4
- package/lib/stack/compute/histograms.js +0 -4
- package/lib/stack/compute/max.js +0 -3
- package/lib/stack/compute/median.js +0 -4
- package/lib/stack/compute/min.js +0 -3
- package/lib/stack/extend.js +1 -11
- package/lib/stack/transform/matchAndCrop.js +6 -19
- package/lib/stack/utility/averageImage.js +0 -9
- package/lib/stack/utility/maxImage.js +0 -7
- package/lib/stack/utility/minImage.js +0 -7
- package/lib/util/Shape.js +3 -40
- package/lib/util/base64.js +3 -14
- package/lib/util/channel.js +1 -35
- package/lib/util/color.js +1 -25
- package/lib/util/converter.js +1 -13
- package/lib/util/deepValue.js +0 -3
- package/lib/util/histogram.js +1 -12
- package/lib/util/kernel.js +2 -12
- package/lib/util/matrix.js +0 -13
- package/lib/util/points.js +12 -35
- package/lib/util/value.js +0 -7
- package/lib/util/zerosMatrix.js +0 -3
- package/package.json +2 -2
- package/src/image/operator/paintLabels.js +6 -6
- package/src/image/operator/paintPolygon.js +1 -1
- package/src/image/operator/paintPolygons.js +2 -2
- package/src/image/operator/paintPolylines.js +1 -1
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = cmyk;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
9
|
-
|
|
10
8
|
var _model = require("../model/model");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
// http://www.easyrgb.com/index.php?X=MATH&H=18#text18
|
|
15
11
|
// check rgbToHsl : https://bgrins.github.io/TinyColor/docs/tinycolor.html
|
|
16
12
|
|
|
@@ -31,15 +27,12 @@ function cmyk() {
|
|
|
31
27
|
alpha: [0, 1],
|
|
32
28
|
colorModel: [_model.RGB]
|
|
33
29
|
});
|
|
34
|
-
|
|
35
30
|
let newImage = _Image.default.createFrom(this, {
|
|
36
31
|
components: 4,
|
|
37
32
|
colorModel: _model.CMYK
|
|
38
33
|
});
|
|
39
|
-
|
|
40
34
|
let ptr = 0;
|
|
41
35
|
let data = this.data;
|
|
42
|
-
|
|
43
36
|
for (let i = 0; i < data.length; i += this.channels) {
|
|
44
37
|
let red = data[i];
|
|
45
38
|
let green = data[i + 1];
|
|
@@ -52,11 +45,9 @@ function cmyk() {
|
|
|
52
45
|
newImage.data[ptr++] = Math.round(magenta);
|
|
53
46
|
newImage.data[ptr++] = Math.round(yellow);
|
|
54
47
|
newImage.data[ptr++] = Math.round(black);
|
|
55
|
-
|
|
56
48
|
if (this.alpha) {
|
|
57
49
|
newImage.data[ptr++] = data[i + 3];
|
|
58
50
|
}
|
|
59
51
|
}
|
|
60
|
-
|
|
61
52
|
return newImage;
|
|
62
53
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = colorDepth;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Change the image color depth.
|
|
14
11
|
* The color depth is the number of bits that is assigned to each point of a channel.
|
|
@@ -25,19 +22,15 @@ function colorDepth(newColorDepth = 8) {
|
|
|
25
22
|
this.checkProcessable('colorDepth', {
|
|
26
23
|
bitDepth: [1, 8, 16]
|
|
27
24
|
});
|
|
28
|
-
|
|
29
25
|
if (![8, 16].includes(newColorDepth)) {
|
|
30
26
|
throw Error('You need to specify the new colorDepth as 8 or 16');
|
|
31
27
|
}
|
|
32
|
-
|
|
33
28
|
if (this.bitDepth === newColorDepth) {
|
|
34
29
|
return this.clone();
|
|
35
30
|
}
|
|
36
|
-
|
|
37
31
|
let newImage = _Image.default.createFrom(this, {
|
|
38
32
|
bitDepth: newColorDepth
|
|
39
33
|
});
|
|
40
|
-
|
|
41
34
|
switch (newColorDepth) {
|
|
42
35
|
case 8:
|
|
43
36
|
if (this.bitDepth === 1) {
|
|
@@ -51,9 +44,7 @@ function colorDepth(newColorDepth = 8) {
|
|
|
51
44
|
newImage.data[i] = this.data[i] >> 8;
|
|
52
45
|
}
|
|
53
46
|
}
|
|
54
|
-
|
|
55
47
|
break;
|
|
56
|
-
|
|
57
48
|
case 16:
|
|
58
49
|
if (this.bitDepth === 1) {
|
|
59
50
|
for (let i = 0; i < this.size; i++) {
|
|
@@ -66,12 +57,9 @@ function colorDepth(newColorDepth = 8) {
|
|
|
66
57
|
newImage.data[i] = this.data[i] << 8 | this.data[i];
|
|
67
58
|
}
|
|
68
59
|
}
|
|
69
|
-
|
|
70
60
|
break;
|
|
71
|
-
|
|
72
61
|
default:
|
|
73
62
|
throw new Error('colorDepth conversion unexpected case');
|
|
74
63
|
}
|
|
75
|
-
|
|
76
64
|
return newImage;
|
|
77
65
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = crop;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Crops the image
|
|
14
11
|
* @memberof Image
|
|
@@ -39,25 +36,19 @@ function crop(options = {}) {
|
|
|
39
36
|
y = Math.round(y);
|
|
40
37
|
width = Math.round(width);
|
|
41
38
|
height = Math.round(height);
|
|
42
|
-
|
|
43
39
|
if (x > this.width - 1 || y > this.height - 1) {
|
|
44
40
|
throw new RangeError(`crop: origin (x:${x}, y:${y}) out of range (${this.width - 1}; ${this.height - 1})`);
|
|
45
41
|
}
|
|
46
|
-
|
|
47
42
|
if (width <= 0 || height <= 0) {
|
|
48
43
|
throw new RangeError(`crop: width and height (width:${width}; height:${height}) must be positive numbers`);
|
|
49
44
|
}
|
|
50
|
-
|
|
51
45
|
if (x < 0 || y < 0) {
|
|
52
46
|
throw new RangeError(`crop: x and y (x:${x}, y:${y}) must be positive numbers`);
|
|
53
47
|
}
|
|
54
|
-
|
|
55
48
|
if (width > this.width - x || height > this.height - y) {
|
|
56
49
|
throw new RangeError(`crop: (x: ${x}, y:${y}, width:${width}, height:${height}) size is out of range`);
|
|
57
50
|
}
|
|
58
|
-
|
|
59
51
|
let result = this;
|
|
60
|
-
|
|
61
52
|
if (this.bitDepth === 1) {
|
|
62
53
|
const newImage = new _Image.default(width, height, {
|
|
63
54
|
kind: 'BINARY',
|
|
@@ -70,51 +61,40 @@ function crop(options = {}) {
|
|
|
70
61
|
height,
|
|
71
62
|
position: [x, y]
|
|
72
63
|
});
|
|
73
|
-
|
|
74
64
|
result = cropDefault(this, newImage, x, y, width, height);
|
|
75
65
|
}
|
|
76
|
-
|
|
77
66
|
return result;
|
|
78
67
|
}
|
|
79
|
-
|
|
80
68
|
function cropDefault(img, newImage, x, y, width, height) {
|
|
81
69
|
let xWidth = width * img.channels;
|
|
82
70
|
let y1 = y + height;
|
|
83
71
|
let ptr = 0; // pointer for new array
|
|
84
72
|
|
|
85
73
|
let jLeft = x * img.channels;
|
|
86
|
-
|
|
87
74
|
for (let i = y; i < y1; i++) {
|
|
88
75
|
let j = i * img.width * img.channels + jLeft;
|
|
89
76
|
let jL = j + xWidth;
|
|
90
|
-
|
|
91
77
|
for (; j < jL; j++) {
|
|
92
78
|
newImage.data[ptr++] = img.data[j];
|
|
93
79
|
}
|
|
94
80
|
}
|
|
95
|
-
|
|
96
81
|
return newImage;
|
|
97
82
|
}
|
|
98
|
-
|
|
99
83
|
function cropBinary(img, newImage, x, y, width, height) {
|
|
100
84
|
let xWidth = width * img.channels;
|
|
101
85
|
let y1 = y + height;
|
|
102
86
|
let ptr = 0; // pointer for new array
|
|
103
87
|
|
|
104
88
|
let jLeft = x * img.channels;
|
|
105
|
-
|
|
106
89
|
for (let i = y; i < y1; i++) {
|
|
107
90
|
let j = i * img.width * img.channels + jLeft;
|
|
108
91
|
let jL = j + xWidth;
|
|
109
|
-
|
|
110
92
|
for (; j < jL; j++) {
|
|
111
93
|
if (img.getBit(j)) {
|
|
112
94
|
newImage.setBit(ptr);
|
|
113
95
|
}
|
|
114
|
-
|
|
115
96
|
++ptr;
|
|
116
97
|
}
|
|
117
98
|
}
|
|
118
|
-
|
|
119
99
|
return newImage;
|
|
120
100
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = cropAlpha;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Crops the image based on the alpha channel
|
|
10
9
|
* This removes lines and columns where the alpha channel is lower than a threshold value.
|
|
@@ -22,11 +21,9 @@ function cropAlpha(options = {}) {
|
|
|
22
21
|
threshold = this.maxValue
|
|
23
22
|
} = options;
|
|
24
23
|
let left = findLeft(this, threshold, this.components);
|
|
25
|
-
|
|
26
24
|
if (left === -1) {
|
|
27
25
|
throw new Error('Could not find new dimensions. Threshold may be too high.');
|
|
28
26
|
}
|
|
29
|
-
|
|
30
27
|
let top = findTop(this, threshold, this.components, left);
|
|
31
28
|
let bottom = findBottom(this, threshold, this.components, left);
|
|
32
29
|
let right = findRight(this, threshold, this.components, left, top, bottom);
|
|
@@ -37,7 +34,6 @@ function cropAlpha(options = {}) {
|
|
|
37
34
|
height: bottom - top + 1
|
|
38
35
|
});
|
|
39
36
|
}
|
|
40
|
-
|
|
41
37
|
function findLeft(image, threshold, channel) {
|
|
42
38
|
for (let x = 0; x < image.width; x++) {
|
|
43
39
|
for (let y = 0; y < image.height; y++) {
|
|
@@ -46,10 +42,8 @@ function findLeft(image, threshold, channel) {
|
|
|
46
42
|
}
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
|
-
|
|
50
45
|
return -1;
|
|
51
46
|
}
|
|
52
|
-
|
|
53
47
|
function findTop(image, threshold, channel, left) {
|
|
54
48
|
for (let y = 0; y < image.height; y++) {
|
|
55
49
|
for (let x = left; x < image.width; x++) {
|
|
@@ -58,10 +52,8 @@ function findTop(image, threshold, channel, left) {
|
|
|
58
52
|
}
|
|
59
53
|
}
|
|
60
54
|
}
|
|
61
|
-
|
|
62
55
|
return -1;
|
|
63
56
|
}
|
|
64
|
-
|
|
65
57
|
function findBottom(image, threshold, channel, left) {
|
|
66
58
|
for (let y = image.height - 1; y >= 0; y--) {
|
|
67
59
|
for (let x = left; x < image.width; x++) {
|
|
@@ -70,10 +62,8 @@ function findBottom(image, threshold, channel, left) {
|
|
|
70
62
|
}
|
|
71
63
|
}
|
|
72
64
|
}
|
|
73
|
-
|
|
74
65
|
return -1;
|
|
75
66
|
}
|
|
76
|
-
|
|
77
67
|
function findRight(image, threshold, channel, left, top, bottom) {
|
|
78
68
|
for (let x = image.width - 1; x >= left; x--) {
|
|
79
69
|
for (let y = top; y <= bottom; y++) {
|
|
@@ -82,6 +72,5 @@ function findRight(image, threshold, channel, left, top, bottom) {
|
|
|
82
72
|
}
|
|
83
73
|
}
|
|
84
74
|
}
|
|
85
|
-
|
|
86
75
|
return -1;
|
|
87
76
|
}
|
|
@@ -4,15 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = grey;
|
|
7
|
-
|
|
8
7
|
var _clamp = require("../internal/clamp");
|
|
9
|
-
|
|
10
8
|
var _getOutputImage = require("../internal/getOutputImage");
|
|
11
|
-
|
|
12
9
|
var _model = require("../model/model");
|
|
13
|
-
|
|
14
10
|
var _greyAlgorithms = require("./greyAlgorithms");
|
|
15
|
-
|
|
16
11
|
/**
|
|
17
12
|
* Call back that converts the RGB channels to grey. It will be clamped after.
|
|
18
13
|
* @callback GreyAlgorithmCallback
|
|
@@ -44,57 +39,46 @@ function grey(options = {}) {
|
|
|
44
39
|
keepAlpha = false,
|
|
45
40
|
mergeAlpha = true
|
|
46
41
|
} = options;
|
|
47
|
-
|
|
48
42
|
if (typeof algorithm !== 'string' && typeof algorithm !== 'function') {
|
|
49
43
|
throw new TypeError('algorithm must be a string or a function');
|
|
50
44
|
}
|
|
51
|
-
|
|
52
45
|
this.checkProcessable('grey', {
|
|
53
46
|
bitDepth: [8, 16],
|
|
54
47
|
alpha: [0, 1]
|
|
55
48
|
});
|
|
56
|
-
|
|
57
49
|
if (this.components === 1) {
|
|
58
50
|
algorithm = 'red'; // actually we just take the first channel if it is a grey image
|
|
59
51
|
}
|
|
60
52
|
|
|
61
53
|
keepAlpha &= this.alpha;
|
|
62
54
|
mergeAlpha &= this.alpha;
|
|
63
|
-
|
|
64
55
|
if (keepAlpha) {
|
|
65
56
|
mergeAlpha = false;
|
|
66
57
|
}
|
|
67
|
-
|
|
68
58
|
let newImage = (0, _getOutputImage.getOutputImage)(this, options, {
|
|
69
59
|
components: 1,
|
|
70
60
|
alpha: keepAlpha,
|
|
71
61
|
colorModel: _model.GREY
|
|
72
62
|
});
|
|
73
63
|
let method;
|
|
74
|
-
|
|
75
64
|
if (typeof algorithm === 'function') {
|
|
76
65
|
method = algorithm;
|
|
77
66
|
} else {
|
|
78
67
|
method = _greyAlgorithms.methods[algorithm.toLowerCase()];
|
|
79
|
-
|
|
80
68
|
if (!method) {
|
|
81
69
|
throw new Error(`unsupported grey algorithm: ${algorithm}`);
|
|
82
70
|
}
|
|
83
71
|
}
|
|
84
|
-
|
|
85
72
|
let ptr = 0;
|
|
86
|
-
|
|
87
73
|
for (let i = 0; i < this.data.length; i += this.channels) {
|
|
88
74
|
if (mergeAlpha) {
|
|
89
75
|
newImage.data[ptr++] = (0, _clamp.clamp)(method(this.data[i], this.data[i + 1], this.data[i + 2], this) * this.data[i + this.components] / this.maxValue, this);
|
|
90
76
|
} else {
|
|
91
77
|
newImage.data[ptr++] = (0, _clamp.clamp)(method(this.data[i], this.data[i + 1], this.data[i + 2], this), this);
|
|
92
|
-
|
|
93
78
|
if (newImage.alpha) {
|
|
94
79
|
newImage.data[ptr++] = this.data[i + this.components];
|
|
95
80
|
}
|
|
96
81
|
}
|
|
97
82
|
}
|
|
98
|
-
|
|
99
83
|
return newImage;
|
|
100
84
|
}
|
|
@@ -4,10 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.names = exports.methods = void 0;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* @typedef {('luma709'|'luma601'|'maximum'|'minimum'|'average'|'minmax'|'red'|'green'|'blue'|'cyan'|'magenta'|'yellow'|'black'|'hue'|'saturation'|'lightness')} GreyAlgorithm
|
|
10
9
|
*/
|
|
10
|
+
|
|
11
11
|
const methods = {
|
|
12
12
|
luma709(red, green, blue) {
|
|
13
13
|
// sRGB
|
|
@@ -19,91 +19,70 @@ const methods = {
|
|
|
19
19
|
// Same result, > 10% faster on the full grey conversion
|
|
20
20
|
return red * 6966 + green * 23436 + blue * 2366 >> 15;
|
|
21
21
|
},
|
|
22
|
-
|
|
23
22
|
luma601(red, green, blue) {
|
|
24
23
|
// NTSC
|
|
25
24
|
// return this.red * 0.299 + green * 0.587 + blue * 0.114;
|
|
26
25
|
return red * 9798 + green * 19235 + blue * 3735 >> 15;
|
|
27
26
|
},
|
|
28
|
-
|
|
29
27
|
maximum(red, green, blue) {
|
|
30
28
|
return Math.max(red, green, blue);
|
|
31
29
|
},
|
|
32
|
-
|
|
33
30
|
minimum(red, green, blue) {
|
|
34
31
|
return Math.min(red, green, blue);
|
|
35
32
|
},
|
|
36
|
-
|
|
37
33
|
average(red, green, blue) {
|
|
38
34
|
return (red + green + blue) / 3 >> 0;
|
|
39
35
|
},
|
|
40
|
-
|
|
41
36
|
minmax(red, green, blue) {
|
|
42
37
|
return (Math.max(red, green, blue) + Math.min(red, green, blue)) / 2;
|
|
43
38
|
},
|
|
44
|
-
|
|
45
39
|
red(red) {
|
|
46
40
|
return red;
|
|
47
41
|
},
|
|
48
|
-
|
|
49
42
|
green(red, green) {
|
|
50
43
|
return green;
|
|
51
44
|
},
|
|
52
|
-
|
|
53
45
|
blue(red, green, blue) {
|
|
54
46
|
return blue;
|
|
55
47
|
},
|
|
56
|
-
|
|
57
48
|
cyan(red, green, blue, image) {
|
|
58
49
|
let black = methods.black(red, green, blue, image);
|
|
59
50
|
return (image.maxValue - red - black) / (1 - black / image.maxValue) >> 0;
|
|
60
51
|
},
|
|
61
|
-
|
|
62
52
|
magenta(red, green, blue, image) {
|
|
63
53
|
let black = methods.black(red, green, blue, image);
|
|
64
54
|
return (image.maxValue - green - black) / (1 - black / image.maxValue) >> 0;
|
|
65
55
|
},
|
|
66
|
-
|
|
67
56
|
yellow(red, green, blue, image) {
|
|
68
57
|
let black = methods.black(red, green, blue, image);
|
|
69
58
|
return (image.maxValue - blue - black) / (1 - black / image.maxValue) >> 0;
|
|
70
59
|
},
|
|
71
|
-
|
|
72
60
|
black(red, green, blue, image) {
|
|
73
61
|
return Math.min(image.maxValue - red, image.maxValue - green, image.maxValue - blue);
|
|
74
62
|
},
|
|
75
|
-
|
|
76
63
|
hue(red, green, blue, image) {
|
|
77
64
|
let min = methods.min(red, green, blue);
|
|
78
65
|
let max = methods.max(red, green, blue);
|
|
79
|
-
|
|
80
66
|
if (max === min) {
|
|
81
67
|
return 0;
|
|
82
68
|
}
|
|
83
|
-
|
|
84
69
|
let hue = 0;
|
|
85
70
|
let delta = max - min;
|
|
86
|
-
|
|
87
71
|
switch (max) {
|
|
88
72
|
case red:
|
|
89
73
|
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
90
74
|
break;
|
|
91
|
-
|
|
92
75
|
case green:
|
|
93
76
|
hue = (blue - red) / delta + 2;
|
|
94
77
|
break;
|
|
95
|
-
|
|
96
78
|
case blue:
|
|
97
79
|
hue = (red - green) / delta + 4;
|
|
98
80
|
break;
|
|
99
|
-
|
|
100
81
|
default:
|
|
101
82
|
throw new Error('unreachable');
|
|
102
83
|
}
|
|
103
|
-
|
|
104
84
|
return hue / 6 * image.maxValue >> 0;
|
|
105
85
|
},
|
|
106
|
-
|
|
107
86
|
saturation(red, green, blue, image) {
|
|
108
87
|
// from HSV model
|
|
109
88
|
let min = methods.min(red, green, blue);
|
|
@@ -111,13 +90,11 @@ const methods = {
|
|
|
111
90
|
let delta = max - min;
|
|
112
91
|
return max === 0 ? 0 : delta / max * image.maxValue;
|
|
113
92
|
},
|
|
114
|
-
|
|
115
93
|
lightness(red, green, blue) {
|
|
116
94
|
let min = methods.min(red, green, blue);
|
|
117
95
|
let max = methods.max(red, green, blue);
|
|
118
96
|
return (max + min) / 2;
|
|
119
97
|
}
|
|
120
|
-
|
|
121
98
|
};
|
|
122
99
|
exports.methods = methods;
|
|
123
100
|
Object.defineProperty(methods, 'luminosity', {
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = hsl;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
9
|
-
|
|
10
8
|
var _model = require("../model/model");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
// http://www.easyrgb.com/index.php?X=MATH&H=18#text18
|
|
15
11
|
// check rgbToHsl : https://bgrins.github.io/TinyColor/docs/tinycolor.html
|
|
16
12
|
|
|
@@ -31,15 +27,12 @@ function hsl() {
|
|
|
31
27
|
alpha: [0, 1],
|
|
32
28
|
colorModel: [_model.RGB]
|
|
33
29
|
});
|
|
34
|
-
|
|
35
30
|
let newImage = _Image.default.createFrom(this, {
|
|
36
31
|
colorModel: _model.HSL
|
|
37
32
|
});
|
|
38
|
-
|
|
39
33
|
let threshold = Math.floor(this.maxValue / 2);
|
|
40
34
|
let ptr = 0;
|
|
41
35
|
let data = this.data;
|
|
42
|
-
|
|
43
36
|
for (let i = 0; i < data.length; i += this.channels) {
|
|
44
37
|
let red = data[i];
|
|
45
38
|
let green = data[i + 1];
|
|
@@ -49,39 +42,30 @@ function hsl() {
|
|
|
49
42
|
let hue = 0;
|
|
50
43
|
let saturation = 0;
|
|
51
44
|
let luminance = (max + min) / 2;
|
|
52
|
-
|
|
53
45
|
if (max !== min) {
|
|
54
46
|
let delta = max - min;
|
|
55
47
|
saturation = luminance > threshold ? delta / (2 - max - min) : delta / (max + min);
|
|
56
|
-
|
|
57
48
|
switch (max) {
|
|
58
49
|
case red:
|
|
59
50
|
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
60
51
|
break;
|
|
61
|
-
|
|
62
52
|
case green:
|
|
63
53
|
hue = (blue - red) / delta + 2;
|
|
64
54
|
break;
|
|
65
|
-
|
|
66
55
|
case blue:
|
|
67
56
|
hue = (red - green) / delta + 4;
|
|
68
57
|
break;
|
|
69
|
-
|
|
70
58
|
default:
|
|
71
59
|
throw new Error('unreachable');
|
|
72
60
|
}
|
|
73
|
-
|
|
74
61
|
hue /= 6;
|
|
75
62
|
}
|
|
76
|
-
|
|
77
63
|
newImage.data[ptr++] = hue * this.maxValue;
|
|
78
64
|
newImage.data[ptr++] = saturation * this.maxValue;
|
|
79
65
|
newImage.data[ptr++] = luminance;
|
|
80
|
-
|
|
81
66
|
if (this.alpha) {
|
|
82
67
|
newImage.data[ptr++] = data[i + 3];
|
|
83
68
|
}
|
|
84
69
|
}
|
|
85
|
-
|
|
86
70
|
return newImage;
|
|
87
71
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = hsv;
|
|
7
|
-
|
|
8
7
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
9
|
-
|
|
10
8
|
var _model = require("../model/model");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
// based on https://bgrins.github.io/TinyColor/docs/tinycolor.html
|
|
15
11
|
|
|
16
12
|
/**
|
|
@@ -30,14 +26,11 @@ function hsv() {
|
|
|
30
26
|
alpha: [0, 1],
|
|
31
27
|
colorModel: [_model.RGB]
|
|
32
28
|
});
|
|
33
|
-
|
|
34
29
|
let newImage = _Image.default.createFrom(this, {
|
|
35
30
|
colorModel: _model.HSV
|
|
36
31
|
});
|
|
37
|
-
|
|
38
32
|
let ptr = 0;
|
|
39
33
|
let data = this.data;
|
|
40
|
-
|
|
41
34
|
for (let i = 0; i < data.length; i += this.channels) {
|
|
42
35
|
let red = data[i];
|
|
43
36
|
let green = data[i + 1];
|
|
@@ -48,36 +41,28 @@ function hsv() {
|
|
|
48
41
|
let hue = 0;
|
|
49
42
|
let saturation = max === 0 ? 0 : delta / max;
|
|
50
43
|
let value = max;
|
|
51
|
-
|
|
52
44
|
if (max !== min) {
|
|
53
45
|
switch (max) {
|
|
54
46
|
case red:
|
|
55
47
|
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
56
48
|
break;
|
|
57
|
-
|
|
58
49
|
case green:
|
|
59
50
|
hue = (blue - red) / delta + 2;
|
|
60
51
|
break;
|
|
61
|
-
|
|
62
52
|
case blue:
|
|
63
53
|
hue = (red - green) / delta + 4;
|
|
64
54
|
break;
|
|
65
|
-
|
|
66
55
|
default:
|
|
67
56
|
throw new Error('unreachable');
|
|
68
57
|
}
|
|
69
|
-
|
|
70
58
|
hue /= 6;
|
|
71
59
|
}
|
|
72
|
-
|
|
73
60
|
newImage.data[ptr++] = hue * this.maxValue;
|
|
74
61
|
newImage.data[ptr++] = saturation * this.maxValue;
|
|
75
62
|
newImage.data[ptr++] = value;
|
|
76
|
-
|
|
77
63
|
if (this.alpha) {
|
|
78
64
|
newImage.data[ptr++] = data[i + 3];
|
|
79
65
|
}
|
|
80
66
|
}
|
|
81
|
-
|
|
82
67
|
return newImage;
|
|
83
68
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = insert;
|
|
7
|
-
|
|
8
7
|
var _getImageParameters = _interopRequireDefault(require("../internal/getImageParameters"));
|
|
9
|
-
|
|
10
8
|
var _getOutputImage = require("../internal/getOutputImage");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Inserts an image within another image.
|
|
16
12
|
* @memberof Image
|
|
@@ -34,7 +30,6 @@ function insert(toInsert, options = {}) {
|
|
|
34
30
|
});
|
|
35
31
|
const maxY = Math.min(out.height, y + toInsert.height);
|
|
36
32
|
const maxX = Math.min(out.width, x + toInsert.width);
|
|
37
|
-
|
|
38
33
|
if (out.bitDepth === 1) {
|
|
39
34
|
for (let j = y; j < maxY; j++) {
|
|
40
35
|
for (let i = x; i < maxX; i++) {
|
|
@@ -49,6 +44,5 @@ function insert(toInsert, options = {}) {
|
|
|
49
44
|
}
|
|
50
45
|
}
|
|
51
46
|
}
|
|
52
|
-
|
|
53
47
|
return out;
|
|
54
48
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = huang;
|
|
7
|
-
|
|
8
7
|
/*
|
|
9
8
|
*
|
|
10
9
|
* see http://rsb.info.nih.gov/ij/developer/source/ij/process/AutoThresholder.java.html.
|
|
@@ -12,82 +11,68 @@ exports.default = huang;
|
|
|
12
11
|
* "Image thresholding by minimizing the measure of fuzziness", Pattern Recognition 28(1): 41-51
|
|
13
12
|
*
|
|
14
13
|
*/
|
|
14
|
+
|
|
15
15
|
function huang(histogram) {
|
|
16
16
|
/* Determine the first non-zero bin */
|
|
17
17
|
let firstBin = 0;
|
|
18
|
-
|
|
19
18
|
for (let ih = 0; ih < histogram.length; ih++) {
|
|
20
19
|
if (histogram[ih] !== 0) {
|
|
21
20
|
firstBin = ih;
|
|
22
21
|
break;
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
|
-
/* Determine the last non-zero bin */
|
|
26
|
-
|
|
27
24
|
|
|
25
|
+
/* Determine the last non-zero bin */
|
|
28
26
|
let lastBin = histogram.length - 1;
|
|
29
|
-
|
|
30
27
|
for (let ih = histogram.length - 1; ih >= firstBin; ih--) {
|
|
31
28
|
if (histogram[ih] !== 0) {
|
|
32
29
|
lastBin = ih;
|
|
33
30
|
break;
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
|
-
|
|
37
33
|
let term = 1.0 / (lastBin - firstBin);
|
|
38
34
|
let mu0 = new Array(histogram.length);
|
|
39
35
|
let sumPix = 0;
|
|
40
36
|
let numPix = 0;
|
|
41
|
-
|
|
42
37
|
for (let ih = firstBin; ih < histogram.length; ih++) {
|
|
43
38
|
sumPix += ih * histogram[ih];
|
|
44
39
|
numPix += histogram[ih];
|
|
45
40
|
mu0[ih] = sumPix / numPix;
|
|
46
41
|
}
|
|
47
|
-
|
|
48
42
|
let mu1 = new Array(histogram.length);
|
|
49
43
|
sumPix = numPix = 0;
|
|
50
|
-
|
|
51
44
|
for (let ih = lastBin; ih > 0; ih--) {
|
|
52
45
|
sumPix += ih * histogram[ih];
|
|
53
46
|
numPix += histogram[ih];
|
|
54
47
|
mu1[ih - 1] = sumPix / numPix;
|
|
55
48
|
}
|
|
56
|
-
/* Determine the threshold that minimizes the fuzzy entropy*/
|
|
57
|
-
|
|
58
49
|
|
|
50
|
+
/* Determine the threshold that minimizes the fuzzy entropy*/
|
|
59
51
|
let threshold = -1;
|
|
60
52
|
let minEnt = Number.MAX_VALUE;
|
|
61
|
-
|
|
62
53
|
for (let it = 0; it < histogram.length; it++) {
|
|
63
54
|
let ent = 0;
|
|
64
55
|
let muX;
|
|
65
|
-
|
|
66
56
|
for (let ih = 0; ih <= it; ih++) {
|
|
67
57
|
/* Equation (4) in Ref. 1 */
|
|
68
58
|
muX = 1 / (1 + term * Math.abs(ih - mu0[it]));
|
|
69
|
-
|
|
70
59
|
if (!(muX < 1e-6 || muX > 0.999999)) {
|
|
71
60
|
/* Equation (6) & (8) in Ref. 1 */
|
|
72
61
|
ent += histogram[ih] * (-muX * Math.log(muX) - (1 - muX) * Math.log(1 - muX));
|
|
73
62
|
}
|
|
74
63
|
}
|
|
75
|
-
|
|
76
64
|
for (let ih = it + 1; ih < histogram.length; ih++) {
|
|
77
65
|
/* Equation (4) in Ref. 1 */
|
|
78
66
|
muX = 1 / (1 + term * Math.abs(ih - mu1[it]));
|
|
79
|
-
|
|
80
67
|
if (!(muX < 1e-6 || muX > 0.999999)) {
|
|
81
68
|
/* Equation (6) & (8) in Ref. 1 */
|
|
82
69
|
ent += histogram[ih] * (-muX * Math.log(muX) - (1 - muX) * Math.log(1 - muX));
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
|
-
|
|
86
72
|
if (ent < minEnt) {
|
|
87
73
|
minEnt = ent;
|
|
88
74
|
threshold = it;
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
|
-
|
|
92
77
|
return threshold;
|
|
93
78
|
}
|