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,23 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = convolution;
|
|
7
|
-
|
|
8
7
|
var _mlMatrixConvolution = require("ml-matrix-convolution");
|
|
9
|
-
|
|
10
8
|
var _channel = require("../../util/channel");
|
|
11
|
-
|
|
12
9
|
var _kernel = require("../../util/kernel");
|
|
13
|
-
|
|
14
10
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
15
|
-
|
|
16
11
|
var _clamp = require("../internal/clamp");
|
|
17
|
-
|
|
18
12
|
var _convolutionSeparable = _interopRequireDefault(require("./convolutionSeparable"));
|
|
19
|
-
|
|
20
13
|
var _getSeparatedKernel = _interopRequireDefault(require("./getSeparatedKernel"));
|
|
21
|
-
|
|
22
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
-
|
|
24
15
|
/**
|
|
25
16
|
* @memberof Image
|
|
26
17
|
* @instance
|
|
@@ -47,11 +38,8 @@ function convolution(kernel, options = {}) {
|
|
|
47
38
|
} = options;
|
|
48
39
|
let createOptions = {};
|
|
49
40
|
if (bitDepth) createOptions.bitDepth = bitDepth;
|
|
50
|
-
|
|
51
41
|
let newImage = _Image.default.createFrom(this, createOptions);
|
|
52
|
-
|
|
53
42
|
channels = (0, _channel.validateArrayOfChannels)(this, channels, true);
|
|
54
|
-
|
|
55
43
|
if (algorithm !== 'separable') {
|
|
56
44
|
({
|
|
57
45
|
kernel
|
|
@@ -59,10 +47,8 @@ function convolution(kernel, options = {}) {
|
|
|
59
47
|
} else if (!Array.isArray(kernel) || kernel.length !== 2) {
|
|
60
48
|
throw new RangeError('separable convolution requires two arrays of numbers to represent the kernel');
|
|
61
49
|
}
|
|
62
|
-
|
|
63
50
|
if (algorithm === 'auto') {
|
|
64
51
|
let separatedKernel = (0, _getSeparatedKernel.default)(kernel);
|
|
65
|
-
|
|
66
52
|
if (separatedKernel !== null) {
|
|
67
53
|
algorithm = 'separable';
|
|
68
54
|
kernel = separatedKernel;
|
|
@@ -72,9 +58,7 @@ function convolution(kernel, options = {}) {
|
|
|
72
58
|
algorithm = 'direct';
|
|
73
59
|
}
|
|
74
60
|
}
|
|
75
|
-
|
|
76
61
|
let halfHeight, halfWidth;
|
|
77
|
-
|
|
78
62
|
if (algorithm === 'separable') {
|
|
79
63
|
halfHeight = Math.floor(kernel[0].length / 2);
|
|
80
64
|
halfWidth = Math.floor(kernel[1].length / 2);
|
|
@@ -82,21 +66,18 @@ function convolution(kernel, options = {}) {
|
|
|
82
66
|
halfHeight = Math.floor(kernel.length / 2);
|
|
83
67
|
halfWidth = Math.floor(kernel[0].length / 2);
|
|
84
68
|
}
|
|
85
|
-
|
|
86
69
|
let clamped = newImage.isClamped;
|
|
87
70
|
let tmpData = new Array(this.height * this.width);
|
|
88
71
|
let index, x, y, channel, c, tmpResult;
|
|
89
|
-
|
|
90
72
|
for (channel = 0; channel < channels.length; channel++) {
|
|
91
|
-
c = channels[channel];
|
|
92
|
-
|
|
73
|
+
c = channels[channel];
|
|
74
|
+
// Copy the channel in a single array
|
|
93
75
|
for (y = 0; y < this.height; y++) {
|
|
94
76
|
for (x = 0; x < this.width; x++) {
|
|
95
77
|
index = y * this.width + x;
|
|
96
78
|
tmpData[index] = this.data[index * this.channels + c];
|
|
97
79
|
}
|
|
98
80
|
}
|
|
99
|
-
|
|
100
81
|
if (algorithm === 'direct') {
|
|
101
82
|
tmpResult = (0, _mlMatrixConvolution.direct)(tmpData, kernel, {
|
|
102
83
|
rows: this.height,
|
|
@@ -106,17 +87,14 @@ function convolution(kernel, options = {}) {
|
|
|
106
87
|
});
|
|
107
88
|
} else if (algorithm === 'separable') {
|
|
108
89
|
tmpResult = (0, _convolutionSeparable.default)(tmpData, kernel, this.width, this.height);
|
|
109
|
-
|
|
110
90
|
if (normalize) {
|
|
111
91
|
divisor = 0;
|
|
112
|
-
|
|
113
92
|
for (let i = 0; i < kernel[0].length; i++) {
|
|
114
93
|
for (let j = 0; j < kernel[1].length; j++) {
|
|
115
94
|
divisor += kernel[0][i] * kernel[1][j];
|
|
116
95
|
}
|
|
117
96
|
}
|
|
118
97
|
}
|
|
119
|
-
|
|
120
98
|
if (divisor !== 1) {
|
|
121
99
|
for (let i = 0; i < tmpResult.length; i++) {
|
|
122
100
|
tmpResult[i] /= divisor;
|
|
@@ -129,13 +107,12 @@ function convolution(kernel, options = {}) {
|
|
|
129
107
|
normalize: normalize,
|
|
130
108
|
divisor: divisor
|
|
131
109
|
});
|
|
132
|
-
}
|
|
133
|
-
|
|
110
|
+
}
|
|
134
111
|
|
|
112
|
+
// Copy the result to the output image
|
|
135
113
|
for (y = 0; y < this.height; y++) {
|
|
136
114
|
for (x = 0; x < this.width; x++) {
|
|
137
115
|
index = y * this.width + x;
|
|
138
|
-
|
|
139
116
|
if (clamped) {
|
|
140
117
|
newImage.data[index * this.channels + c] = (0, _clamp.clamp)(tmpResult[index], newImage);
|
|
141
118
|
} else {
|
|
@@ -143,27 +120,25 @@ function convolution(kernel, options = {}) {
|
|
|
143
120
|
}
|
|
144
121
|
}
|
|
145
122
|
}
|
|
146
|
-
}
|
|
123
|
+
}
|
|
124
|
+
// if the kernel was not applied on the alpha channel we just copy it
|
|
147
125
|
// TODO: in general we should copy the channels that where not changed
|
|
148
126
|
// TODO: probably we should just copy the image at the beginning ?
|
|
149
|
-
|
|
150
|
-
|
|
151
127
|
if (this.alpha && !channels.includes(this.channels)) {
|
|
152
128
|
for (x = this.components; x < this.data.length; x = x + this.channels) {
|
|
153
129
|
newImage.data[x] = this.data[x];
|
|
154
130
|
}
|
|
155
|
-
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// I only can have 3 types of borders:
|
|
156
134
|
// 1. Considering the image as periodic: periodic
|
|
157
135
|
// 2. Extend the interior borders: copy
|
|
158
136
|
// 3. fill with a color: set
|
|
159
|
-
|
|
160
|
-
|
|
161
137
|
if (border !== 'periodic') {
|
|
162
138
|
newImage.setBorder({
|
|
163
139
|
size: [halfWidth, halfHeight],
|
|
164
140
|
algorithm: border
|
|
165
141
|
});
|
|
166
142
|
}
|
|
167
|
-
|
|
168
143
|
return newImage;
|
|
169
144
|
}
|
|
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = convolutionSeparable;
|
|
7
|
-
|
|
8
7
|
var _mlConvolution = require("ml-convolution");
|
|
9
|
-
|
|
10
8
|
function convolutionSeparable(data, separatedKernel, width, height) {
|
|
11
9
|
const result = new Array(data.length);
|
|
12
10
|
let tmp, conv, offset, kernel;
|
|
@@ -14,35 +12,27 @@ function convolutionSeparable(data, separatedKernel, width, height) {
|
|
|
14
12
|
offset = (kernel.length - 1) / 2;
|
|
15
13
|
conv = new Array(width + kernel.length - 1);
|
|
16
14
|
tmp = new Array(width);
|
|
17
|
-
|
|
18
15
|
for (let y = 0; y < height; y++) {
|
|
19
16
|
for (let x = 0; x < width; x++) {
|
|
20
17
|
tmp[x] = data[y * width + x];
|
|
21
18
|
}
|
|
22
|
-
|
|
23
19
|
(0, _mlConvolution.directConvolution)(tmp, kernel, conv);
|
|
24
|
-
|
|
25
20
|
for (let x = 0; x < width; x++) {
|
|
26
21
|
result[y * width + x] = conv[offset + x];
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
|
-
|
|
30
24
|
kernel = separatedKernel[0];
|
|
31
25
|
offset = (kernel.length - 1) / 2;
|
|
32
26
|
conv = new Array(height + kernel.length - 1);
|
|
33
27
|
tmp = new Array(height);
|
|
34
|
-
|
|
35
28
|
for (let x = 0; x < width; x++) {
|
|
36
29
|
for (let y = 0; y < height; y++) {
|
|
37
30
|
tmp[y] = result[y * width + x];
|
|
38
31
|
}
|
|
39
|
-
|
|
40
32
|
(0, _mlConvolution.directConvolution)(tmp, kernel, conv);
|
|
41
|
-
|
|
42
33
|
for (let y = 0; y < height; y++) {
|
|
43
34
|
result[y * width + x] = conv[offset + y];
|
|
44
35
|
}
|
|
45
36
|
}
|
|
46
|
-
|
|
47
37
|
return result;
|
|
48
38
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = extract;
|
|
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
|
* Extracts a part of an original image based on a mask. By default the mask may contain
|
|
14
11
|
* a relative position and this part of the original image will be extracted.
|
|
@@ -25,16 +22,15 @@ function extract(mask, options = {}) {
|
|
|
25
22
|
} = options;
|
|
26
23
|
this.checkProcessable('extract', {
|
|
27
24
|
bitDepth: [1, 8, 16]
|
|
28
|
-
});
|
|
25
|
+
});
|
|
29
26
|
|
|
27
|
+
// we need to find the relative position to the parent
|
|
30
28
|
if (!position) {
|
|
31
29
|
position = mask.getRelativePosition(this);
|
|
32
|
-
|
|
33
30
|
if (!position) {
|
|
34
31
|
throw new Error('extract : can not extract an image because the relative position can not be ' + 'determined, try to specify manually the position as an array of 2 elements [x,y].');
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
|
|
38
34
|
if (this.bitDepth > 1) {
|
|
39
35
|
let extract = _Image.default.createFrom(this, {
|
|
40
36
|
width: mask.width,
|
|
@@ -44,22 +40,19 @@ function extract(mask, options = {}) {
|
|
|
44
40
|
position: position,
|
|
45
41
|
parent: this
|
|
46
42
|
});
|
|
47
|
-
|
|
48
43
|
for (let x = 0; x < mask.width; x++) {
|
|
49
44
|
for (let y = 0; y < mask.height; y++) {
|
|
50
45
|
// we copy the point
|
|
51
46
|
for (let channel = 0; channel < this.channels; channel++) {
|
|
52
47
|
let value = this.getValueXY(x + position[0], y + position[1], channel);
|
|
53
48
|
extract.setValueXY(x, y, channel, value);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
}
|
|
50
|
+
// we make it transparent in case it is not in the mask
|
|
57
51
|
if (!mask.getBitXY(x, y)) {
|
|
58
52
|
extract.setValueXY(x, y, this.components, 0);
|
|
59
53
|
}
|
|
60
54
|
}
|
|
61
55
|
}
|
|
62
|
-
|
|
63
56
|
return extract;
|
|
64
57
|
} else {
|
|
65
58
|
let extract = _Image.default.createFrom(this, {
|
|
@@ -68,7 +61,6 @@ function extract(mask, options = {}) {
|
|
|
68
61
|
position: position,
|
|
69
62
|
parent: this
|
|
70
63
|
});
|
|
71
|
-
|
|
72
64
|
for (let y = 0; y < mask.height; y++) {
|
|
73
65
|
for (let x = 0; x < mask.width; x++) {
|
|
74
66
|
if (mask.getBitXY(x, y)) {
|
|
@@ -78,7 +70,6 @@ function extract(mask, options = {}) {
|
|
|
78
70
|
}
|
|
79
71
|
}
|
|
80
72
|
}
|
|
81
|
-
|
|
82
73
|
return extract;
|
|
83
74
|
}
|
|
84
75
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = floodFill;
|
|
7
|
-
|
|
8
7
|
var _fastList = _interopRequireDefault(require("fast-list"));
|
|
9
|
-
|
|
10
8
|
var _Image = _interopRequireDefault(require("../Image"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
function floodFill(options = {}) {
|
|
15
11
|
const {
|
|
16
12
|
x = 0,
|
|
@@ -25,36 +21,29 @@ function floodFill(options = {}) {
|
|
|
25
21
|
if (bit) return destination;
|
|
26
22
|
const queue = new _fastList.default();
|
|
27
23
|
queue.push(new Node(x, y));
|
|
28
|
-
|
|
29
24
|
while (queue.length > 0) {
|
|
30
25
|
const node = queue.shift();
|
|
31
26
|
destination.setBitXY(node.x, node.y);
|
|
32
|
-
|
|
33
27
|
for (let i = node.x + 1; i < this.width; i++) {
|
|
34
28
|
if (!destination.getBitXY(i, node.y) && !this.getBitXY(i, node.y)) {
|
|
35
29
|
destination.setBitXY(i, node.y);
|
|
36
|
-
|
|
37
30
|
if (node.y + 1 < this.height && !this.getBitXY(i, node.y + 1)) {
|
|
38
31
|
queue.push(new Node(i, node.y + 1));
|
|
39
32
|
}
|
|
40
|
-
|
|
41
33
|
if (node.y - 1 >= 0 && !this.getBitXY(i, node.y - 1)) {
|
|
42
34
|
queue.push(new Node(i, node.y - 1));
|
|
43
35
|
}
|
|
44
36
|
} else {
|
|
45
37
|
break;
|
|
46
38
|
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line for-direction
|
|
50
41
|
for (let i = node.x - 1; i >= 0; i++) {
|
|
51
42
|
if (!destination.getBitXY(i, node.y) && !this.getBitXY(i, node.y)) {
|
|
52
43
|
destination.setBitXY(i, node.y);
|
|
53
|
-
|
|
54
44
|
if (node.y + 1 < this.height && !this.getBitXY(i, node.y + 1)) {
|
|
55
45
|
queue.push(new Node(i, node.y + 1));
|
|
56
46
|
}
|
|
57
|
-
|
|
58
47
|
if (node.y - 1 >= 0 && !this.getBitXY(i, node.y - 1)) {
|
|
59
48
|
queue.push(new Node(i, node.y - 1));
|
|
60
49
|
}
|
|
@@ -63,10 +52,8 @@ function floodFill(options = {}) {
|
|
|
63
52
|
}
|
|
64
53
|
}
|
|
65
54
|
}
|
|
66
|
-
|
|
67
55
|
return destination;
|
|
68
56
|
}
|
|
69
|
-
|
|
70
57
|
function Node(x, y) {
|
|
71
58
|
this.x = x;
|
|
72
59
|
this.y = y;
|
|
@@ -4,21 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintLabels;
|
|
7
|
-
|
|
8
7
|
var _color = require("../../util/color");
|
|
9
|
-
|
|
10
8
|
var _model = require("../model/model");
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
|
-
* Paint a
|
|
10
|
+
* Paint a label or labels on the current image.
|
|
14
11
|
* @memberof Image
|
|
15
12
|
* @instance
|
|
16
13
|
*
|
|
17
|
-
* @param {Array<string>}
|
|
18
|
-
* @param {Array<Array
|
|
19
|
-
* @param {object}
|
|
20
|
-
* @param {number
|
|
21
|
-
* @param {Array<Array<number>>|Array<string>} [options.colors] - Array of Array of 3 elements (R, G, B) for each color of each
|
|
14
|
+
* @param {Array<string>} [labels] - Array of labels to display.
|
|
15
|
+
* @param {Array<Array<number>>} [positions] - Array of points [x,y] where the labels should be displayed.
|
|
16
|
+
* @param {object} [options]
|
|
17
|
+
* @param {Array<number>|string} [options.color='red'] - Array of 3 elements (R, G, B) or a valid css color.
|
|
18
|
+
* @param {Array<Array<number>>|Array<string>} [options.colors] - Array of Array of 3 elements (R, G, B) for each color of each label.
|
|
22
19
|
* @param {string|Array<string>} [options.font='12px Helvetica'] - Paint the labels in a different CSS style
|
|
23
20
|
* @param {number|Array<number>} [options.rotate=0] - Rotate each label of a define angle
|
|
24
21
|
* @return {this} The original painted image
|
|
@@ -35,41 +32,34 @@ function paintLabels(labels, positions, options = {}) {
|
|
|
35
32
|
bitDepth: [8, 16],
|
|
36
33
|
colorModel: _model.RGB
|
|
37
34
|
});
|
|
38
|
-
|
|
39
35
|
if (!Array.isArray(labels)) {
|
|
40
36
|
throw Error('paintLabels: labels must be an array');
|
|
41
37
|
}
|
|
42
|
-
|
|
43
38
|
if (!Array.isArray(positions)) {
|
|
44
39
|
throw Error('paintLabels: positions must be an array');
|
|
45
40
|
}
|
|
46
|
-
|
|
47
41
|
if (color && !Array.isArray(color)) {
|
|
48
42
|
color = (0, _color.css2array)(color);
|
|
49
43
|
}
|
|
50
|
-
|
|
51
44
|
if (colors) {
|
|
52
45
|
colors = colors.map(function (color) {
|
|
53
46
|
if (!Array.isArray(color)) {
|
|
54
47
|
return (0, _color.css2array)(color);
|
|
55
48
|
}
|
|
56
|
-
|
|
57
49
|
return color;
|
|
58
50
|
});
|
|
59
51
|
} else {
|
|
60
52
|
colors = [color];
|
|
61
53
|
}
|
|
62
|
-
|
|
63
54
|
if (labels.length !== positions.length) {
|
|
64
55
|
throw Error('paintLabels: positions and labels must be arrays from the same size');
|
|
65
|
-
}
|
|
66
|
-
|
|
56
|
+
}
|
|
67
57
|
|
|
58
|
+
// We convert everything to array so that we can simply loop thourgh all the labels
|
|
68
59
|
if (!Array.isArray(font)) font = [font];
|
|
69
60
|
if (!Array.isArray(rotate)) rotate = [rotate];
|
|
70
61
|
let canvas = this.getCanvas();
|
|
71
62
|
let ctx = canvas.getContext('2d');
|
|
72
|
-
|
|
73
63
|
for (let i = 0; i < labels.length; i++) {
|
|
74
64
|
ctx.save();
|
|
75
65
|
let color = colors[i % colors.length];
|
|
@@ -81,7 +71,6 @@ function paintLabels(labels, positions, options = {}) {
|
|
|
81
71
|
ctx.fillText(labels[i], 0, 0);
|
|
82
72
|
ctx.restore();
|
|
83
73
|
}
|
|
84
|
-
|
|
85
74
|
this.data = Uint8Array.from(ctx.getImageData(0, 0, this.width, this.height).data);
|
|
86
75
|
return this;
|
|
87
76
|
}
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintMasks;
|
|
7
|
-
|
|
8
7
|
var _color = require("../../util/color");
|
|
9
|
-
|
|
10
8
|
var _model = require("../model/model");
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Paint a mask or masks on the current image.
|
|
14
11
|
* @memberof Image
|
|
@@ -43,16 +40,13 @@ function paintMasks(masks, options = {}) {
|
|
|
43
40
|
let colors = (0, _color.getColors)(Object.assign({}, options, {
|
|
44
41
|
numberColors: masks.length
|
|
45
42
|
}));
|
|
46
|
-
|
|
47
43
|
if (!Array.isArray(masks)) {
|
|
48
44
|
masks = [masks];
|
|
49
45
|
}
|
|
50
|
-
|
|
51
46
|
for (let i = 0; i < masks.length; i++) {
|
|
52
|
-
let mask = masks[i];
|
|
53
|
-
|
|
47
|
+
let mask = masks[i];
|
|
48
|
+
// we need to find the parent image to calculate the relative position
|
|
54
49
|
let color = colors[i % colors.length];
|
|
55
|
-
|
|
56
50
|
for (let x = 0; x < mask.width; x++) {
|
|
57
51
|
for (let y = 0; y < mask.height; y++) {
|
|
58
52
|
if (mask.getBitXY(x, y)) {
|
|
@@ -69,20 +63,16 @@ function paintMasks(masks, options = {}) {
|
|
|
69
63
|
}
|
|
70
64
|
}
|
|
71
65
|
}
|
|
72
|
-
|
|
73
66
|
if (Array.isArray(labels) && labels.length > 0) {
|
|
74
67
|
let canvas = this.getCanvas();
|
|
75
68
|
let ctx = canvas.getContext('2d');
|
|
76
69
|
ctx.fillStyle = labelColor;
|
|
77
70
|
ctx.font = labelFont;
|
|
78
|
-
|
|
79
71
|
for (let i = 0; i < Math.min(masks.length, labels.length); i++) {
|
|
80
72
|
let position = labelsPosition[i] ? labelsPosition[i] : masks[i].position;
|
|
81
73
|
ctx.fillText(labels[i], position[0], position[1]);
|
|
82
74
|
}
|
|
83
|
-
|
|
84
75
|
this.data = Uint8Array.from(ctx.getImageData(0, 0, this.width, this.height).data);
|
|
85
76
|
}
|
|
86
|
-
|
|
87
77
|
return this;
|
|
88
78
|
}
|
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintPoints;
|
|
7
|
-
|
|
8
7
|
var _Shape = _interopRequireDefault(require("../../util/Shape"));
|
|
9
|
-
|
|
10
8
|
var _color = require("../../util/color");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Paint pixels on the current image.
|
|
16
12
|
* @memberof Image
|
|
@@ -36,25 +32,20 @@ function paintPoints(points, options = {}) {
|
|
|
36
32
|
}));
|
|
37
33
|
let shapePixels = new _Shape.default(shape).getPoints();
|
|
38
34
|
let numberChannels = Math.min(this.channels, colors[0].length);
|
|
39
|
-
|
|
40
35
|
for (let i = 0; i < points.length; i++) {
|
|
41
36
|
let color = colors[i % colors.length];
|
|
42
37
|
let xP = points[i][0];
|
|
43
38
|
let yP = points[i][1];
|
|
44
|
-
|
|
45
39
|
for (let j = 0; j < shapePixels.length; j++) {
|
|
46
40
|
let xS = shapePixels[j][0];
|
|
47
41
|
let yS = shapePixels[j][1];
|
|
48
|
-
|
|
49
42
|
if (xP + xS >= 0 && yP + yS >= 0 && xP + xS < this.width && yP + yS < this.height) {
|
|
50
43
|
let position = (xP + xS + (yP + yS) * this.width) * this.channels;
|
|
51
|
-
|
|
52
44
|
for (let channel = 0; channel < numberChannels; channel++) {
|
|
53
45
|
this.data[position + channel] = color[channel];
|
|
54
46
|
}
|
|
55
47
|
}
|
|
56
48
|
}
|
|
57
49
|
}
|
|
58
|
-
|
|
59
50
|
return this;
|
|
60
51
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintPolygon;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Paint a polygon defined by an array of points.
|
|
10
9
|
* @memberof Image
|
|
@@ -12,7 +11,7 @@ exports.default = paintPolygon;
|
|
|
12
11
|
* @param {Array<Array<number>>} points - Array of [x,y] points
|
|
13
12
|
* @param {object} [options]
|
|
14
13
|
* @param {Array<number>} [options.color=[max,0,0]] - Array of 3 elements (R, G, B), default is red.
|
|
15
|
-
* @param {
|
|
14
|
+
* @param {boolean} [options.filled=false] - If you want the polygon to be filled or not.
|
|
16
15
|
* @return {this} The original painted image
|
|
17
16
|
*/
|
|
18
17
|
function paintPolygon(points, options = {}) {
|
|
@@ -25,23 +24,18 @@ function paintPolygon(points, options = {}) {
|
|
|
25
24
|
});
|
|
26
25
|
options.closed = true;
|
|
27
26
|
let filteredPoints = deleteDouble(points);
|
|
28
|
-
|
|
29
27
|
if (filled === false) {
|
|
30
28
|
return this.paintPolyline(points, options);
|
|
31
29
|
} else {
|
|
32
30
|
let matrixBinary = Array(this.height);
|
|
33
|
-
|
|
34
31
|
for (let i = 0; i < this.height; i++) {
|
|
35
32
|
matrixBinary[i] = [];
|
|
36
|
-
|
|
37
33
|
for (let j = 0; j < this.width; j++) {
|
|
38
34
|
matrixBinary[i].push(0);
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
|
-
|
|
42
37
|
for (let p = 0; p < filteredPoints.length; p++) {
|
|
43
38
|
const line = lineBetweenTwoPoints(filteredPoints[p], filteredPoints[(p + 1) % filteredPoints.length]);
|
|
44
|
-
|
|
45
39
|
for (let y = 0; y < this.height; y++) {
|
|
46
40
|
for (let x = 0; x < this.width; x++) {
|
|
47
41
|
if (isAtTheRightOfTheLine(x, y, line, this.height)) {
|
|
@@ -50,7 +44,6 @@ function paintPolygon(points, options = {}) {
|
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
}
|
|
53
|
-
|
|
54
47
|
for (let y = 0; y < this.height; y++) {
|
|
55
48
|
for (let x = 0; x < this.width; x++) {
|
|
56
49
|
if (matrixBinary[y][x] === 1) {
|
|
@@ -59,7 +52,6 @@ function paintPolygon(points, options = {}) {
|
|
|
59
52
|
} else {
|
|
60
53
|
let numberChannels = Math.min(this.channels, color.length);
|
|
61
54
|
let position = (x + y * this.width) * this.channels;
|
|
62
|
-
|
|
63
55
|
for (let channel = 0; channel < numberChannels; channel++) {
|
|
64
56
|
this.data[position + channel] = color[channel];
|
|
65
57
|
}
|
|
@@ -67,14 +59,11 @@ function paintPolygon(points, options = {}) {
|
|
|
67
59
|
}
|
|
68
60
|
}
|
|
69
61
|
}
|
|
70
|
-
|
|
71
62
|
return this.paintPolyline(points, options);
|
|
72
63
|
}
|
|
73
64
|
}
|
|
74
|
-
|
|
75
65
|
function deleteDouble(points) {
|
|
76
66
|
let finalPoints = [];
|
|
77
|
-
|
|
78
67
|
for (let i = 0; i < points.length; i++) {
|
|
79
68
|
if (points[i][0] === points[(i + 1) % points.length][0] && points[i][1] === points[(i + 1) % points.length][1]) {
|
|
80
69
|
continue;
|
|
@@ -86,10 +75,8 @@ function deleteDouble(points) {
|
|
|
86
75
|
finalPoints.push(points[i]);
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
|
-
|
|
90
78
|
return finalPoints;
|
|
91
79
|
}
|
|
92
|
-
|
|
93
80
|
function lineBetweenTwoPoints(p1, p2) {
|
|
94
81
|
if (p1[0] === p2[0]) {
|
|
95
82
|
return {
|
|
@@ -107,7 +94,6 @@ function lineBetweenTwoPoints(p1, p2) {
|
|
|
107
94
|
};
|
|
108
95
|
}
|
|
109
96
|
}
|
|
110
|
-
|
|
111
97
|
function isAtTheRightOfTheLine(x, y, line, height) {
|
|
112
98
|
if (line.vertical === true) {
|
|
113
99
|
return line.b <= x;
|
|
@@ -4,14 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintPolygons;
|
|
7
|
-
|
|
8
7
|
var _color = require("../../util/color");
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
|
-
* Paint an array of
|
|
9
|
+
* Paint an array of polygons on the current image.
|
|
12
10
|
* @memberof Image
|
|
13
11
|
* @instance
|
|
14
|
-
* @param {Array<Array<number
|
|
12
|
+
* @param {Array<Array<Array<number>>>} polygons - Array of array of [x,y] points
|
|
15
13
|
* @param {object} [options]
|
|
16
14
|
* @param {Array<number>|string} [options.color] - Array of 3 elements (R, G, B) or a valid css color.
|
|
17
15
|
* @param {Array<Array<number>>|Array<string>} [options.colors] - Array of Array of 3 elements (R, G, B) for each color of each mask
|
|
@@ -28,11 +26,9 @@ function paintPolygons(polygons, options = {}) {
|
|
|
28
26
|
let colors = (0, _color.getColors)(Object.assign({}, options, {
|
|
29
27
|
numberColors: polygons.length
|
|
30
28
|
}));
|
|
31
|
-
|
|
32
29
|
for (let i = 0; i < polygons.length; i++) {
|
|
33
30
|
optionsCopy.color = colors[i % colors.length];
|
|
34
31
|
this.paintPolygon(polygons[i], optionsCopy);
|
|
35
32
|
}
|
|
36
|
-
|
|
37
33
|
return this;
|
|
38
34
|
}
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = paintPolyline;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Paint a polyline defined by an array of points.
|
|
10
9
|
* @memberof Image
|
|
@@ -24,7 +23,6 @@ function paintPolyline(points, options = {}) {
|
|
|
24
23
|
bitDepth: [1, 8, 16]
|
|
25
24
|
});
|
|
26
25
|
let numberChannels = Math.min(this.channels, color.length);
|
|
27
|
-
|
|
28
26
|
for (let i = 0; i < points.length - 1 + closed; i++) {
|
|
29
27
|
let from = points[i];
|
|
30
28
|
let to = points[(i + 1) % points.length];
|
|
@@ -35,27 +33,22 @@ function paintPolyline(points, options = {}) {
|
|
|
35
33
|
let yIncrement = dy / steps;
|
|
36
34
|
let x = from[0];
|
|
37
35
|
let y = from[1];
|
|
38
|
-
|
|
39
36
|
for (let j = 0; j <= steps; j++) {
|
|
40
37
|
let xPoint = Math.round(x);
|
|
41
38
|
let yPoint = Math.round(y);
|
|
42
|
-
|
|
43
39
|
if (xPoint >= 0 && yPoint >= 0 && xPoint < this.width && yPoint < this.height) {
|
|
44
40
|
if (this.bitDepth === 1) {
|
|
45
41
|
this.setBitXY(xPoint, yPoint);
|
|
46
42
|
} else {
|
|
47
43
|
let position = (xPoint + yPoint * this.width) * this.channels;
|
|
48
|
-
|
|
49
44
|
for (let channel = 0; channel < numberChannels; channel++) {
|
|
50
45
|
this.data[position + channel] = color[channel];
|
|
51
46
|
}
|
|
52
47
|
}
|
|
53
48
|
}
|
|
54
|
-
|
|
55
49
|
x = x + xIncrement;
|
|
56
50
|
y = y + yIncrement;
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
|
-
|
|
60
53
|
return this;
|
|
61
54
|
}
|