image-js 1.1.0 → 1.3.0
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/dist/image-js.esm.js +268 -54
- package/dist/image-js.esm.js.map +1 -1
- package/dist/image-js.esm.min.js +2 -2
- package/dist/image-js.esm.min.js.map +1 -1
- package/dist/image-js.umd.js +236 -20
- package/dist/image-js.umd.js.map +1 -1
- package/dist/image-js.umd.min.js +2 -2
- package/dist/image-js.umd.min.js.map +1 -1
- package/dist-types/image-js.d.ts +26 -2
- package/lib/Image.d.ts +17 -1
- package/lib/Image.d.ts.map +1 -1
- package/lib/Image.js +38 -1
- package/lib/Image.js.map +1 -1
- package/lib/draw/drawLineOnImage.d.ts.map +1 -1
- package/lib/draw/drawLineOnImage.js.map +1 -1
- package/lib/extra/draw/draw_text.d.ts +47 -0
- package/lib/extra/draw/draw_text.d.ts.map +1 -0
- package/lib/extra/draw/draw_text.js +108 -0
- package/lib/extra/draw/draw_text.js.map +1 -0
- package/lib/extra/draw/index.d.ts +3 -0
- package/lib/extra/draw/index.d.ts.map +1 -0
- package/lib/extra/draw/index.js +3 -0
- package/lib/extra/draw/index.js.map +1 -0
- package/lib/{ssim → extra/ssim}/compute_dssim.d.ts +2 -2
- package/lib/extra/ssim/compute_dssim.d.ts.map +1 -0
- package/lib/{ssim → extra/ssim}/compute_dssim.js +1 -1
- package/lib/extra/ssim/compute_dssim.js.map +1 -0
- package/lib/{ssim → extra/ssim}/compute_ssim.d.ts +1 -1
- package/lib/extra/ssim/compute_ssim.d.ts.map +1 -0
- package/lib/{ssim → extra/ssim}/compute_ssim.js +2 -2
- package/lib/extra/ssim/compute_ssim.js.map +1 -0
- package/lib/extra/ssim/index.d.ts +3 -0
- package/lib/extra/ssim/index.d.ts.map +1 -0
- package/lib/extra/ssim/index.js +3 -0
- package/lib/extra/ssim/index.js.map +1 -0
- package/lib/index_browser.d.ts +3 -0
- package/lib/index_browser.d.ts.map +1 -0
- package/lib/index_browser.js +5 -0
- package/lib/index_browser.js.map +1 -0
- package/lib/index_full.d.ts +4 -0
- package/lib/index_full.d.ts.map +1 -0
- package/lib/index_full.js +5 -0
- package/lib/index_full.js.map +1 -0
- package/lib/load/decodePng.d.ts.map +1 -1
- package/lib/load/decodePng.js +16 -0
- package/lib/load/decodePng.js.map +1 -1
- package/lib/load/decodeTiff.d.ts.map +1 -1
- package/lib/load/decodeTiff.js +35 -0
- package/lib/load/decodeTiff.js.map +1 -1
- package/lib/load/load.types.d.ts +6 -0
- package/lib/load/load.types.d.ts.map +1 -1
- package/lib/load/read.d.ts +1 -1
- package/lib/load/read.js +1 -1
- package/lib/save/write.d.ts +1 -1
- package/lib/save/write.js +1 -1
- package/lib/utils/cross_platform.d.ts +8 -0
- package/lib/utils/cross_platform.d.ts.map +1 -1
- package/lib/utils/cross_platform.js +34 -2
- package/lib/utils/cross_platform.js.map +1 -1
- package/lib/utils/setBlendedPixel.d.ts +1 -1
- package/lib/utils/setBlendedPixel.js +1 -1
- package/lib/utils/setBlendedVisiblePixel.d.ts +1 -1
- package/lib/utils/setBlendedVisiblePixel.js +1 -1
- package/package.json +17 -3
- package/src/Image.ts +44 -4
- package/src/draw/drawLineOnImage.ts +0 -1
- package/src/extra/draw/draw_text.ts +194 -0
- package/src/extra/draw/index.ts +2 -0
- package/src/{ssim → extra/ssim}/compute_dssim.ts +3 -3
- package/src/{ssim → extra/ssim}/compute_ssim.ts +3 -3
- package/src/extra/ssim/index.ts +2 -0
- package/src/index_browser.ts +4 -0
- package/src/index_full.ts +4 -0
- package/src/load/decodePng.ts +18 -0
- package/src/load/decodeTiff.ts +38 -1
- package/src/load/load.types.ts +8 -0
- package/src/load/read.ts +1 -1
- package/src/save/write.ts +1 -1
- package/src/utils/cross_platform.ts +47 -4
- package/src/utils/setBlendedPixel.ts +1 -1
- package/src/utils/setBlendedVisiblePixel.ts +1 -1
- package/lib/ssim/compute_dssim.d.ts.map +0 -1
- package/lib/ssim/compute_dssim.js.map +0 -1
- package/lib/ssim/compute_ssim.d.ts.map +0 -1
- package/lib/ssim/compute_ssim.js.map +0 -1
- package/lib/ssim/index.d.ts +0 -3
- package/lib/ssim/index.d.ts.map +0 -1
- package/lib/ssim/index.js +0 -3
- package/lib/ssim/index.js.map +0 -1
- package/src/ssim/index.ts +0 -2
package/dist/image-js.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* image-js v1.
|
|
2
|
+
* image-js v1.3.0
|
|
3
3
|
* Image processing and manipulation in JavaScript
|
|
4
4
|
* https://github.com/image-js/image-js#readme
|
|
5
5
|
*
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.IJS = {}));
|
|
12
12
|
})(this, (function (exports) { 'use strict';
|
|
13
13
|
|
|
14
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
14
15
|
function getDefaultExportFromCjs (x) {
|
|
15
16
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
16
17
|
}
|
|
@@ -6269,9 +6270,9 @@ ${indent}columns: ${matrix.columns}
|
|
|
6269
6270
|
var index_umd$1 = {exports: {}};
|
|
6270
6271
|
|
|
6271
6272
|
var index_umd = index_umd$1.exports;
|
|
6272
|
-
(function (module, exports) {
|
|
6273
|
+
(function (module, exports$1) {
|
|
6273
6274
|
(function (N, J) {
|
|
6274
|
-
J(exports) ;
|
|
6275
|
+
J(exports$1) ;
|
|
6275
6276
|
})(index_umd, function (N) {
|
|
6276
6277
|
|
|
6277
6278
|
function J(f, a, o, t, e) {
|
|
@@ -8668,7 +8669,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
8668
8669
|
* @param image - The image with which to blend.
|
|
8669
8670
|
* @param column - Column of the target pixel.
|
|
8670
8671
|
* @param row - Row of the target pixel.
|
|
8671
|
-
* @param color - Color with which to blend the image pixel.
|
|
8672
|
+
* @param color - Color with which to blend the image pixel. Default: `Opaque black`.
|
|
8672
8673
|
*/
|
|
8673
8674
|
function setBlendedPixel(image, column, row, color) {
|
|
8674
8675
|
color = color ?? getDefaultColor(image);
|
|
@@ -8698,7 +8699,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
8698
8699
|
* @param image - The image with which to blend.
|
|
8699
8700
|
* @param column - Column of the target pixel.
|
|
8700
8701
|
* @param row - Row of the target pixel.
|
|
8701
|
-
* @param color - Color with which to blend the image pixel.
|
|
8702
|
+
* @param color - Color with which to blend the image pixel. Default: `Opaque black`.
|
|
8702
8703
|
*/
|
|
8703
8704
|
function setBlendedVisiblePixel(image, column, row, color) {
|
|
8704
8705
|
if (column >= 0 && column < image.width && row >= 0 && row < image.height) {
|
|
@@ -16817,6 +16818,10 @@ ${indent}columns: ${matrix.columns}
|
|
|
16817
16818
|
* Origin of the image relative to a the parent image.
|
|
16818
16819
|
*/
|
|
16819
16820
|
origin;
|
|
16821
|
+
/**
|
|
16822
|
+
* Original image resolution.
|
|
16823
|
+
*/
|
|
16824
|
+
originalResolution;
|
|
16820
16825
|
meta;
|
|
16821
16826
|
/**
|
|
16822
16827
|
* Typed array holding the image data.
|
|
@@ -16837,7 +16842,8 @@ ${indent}columns: ${matrix.columns}
|
|
|
16837
16842
|
row: 0,
|
|
16838
16843
|
column: 0
|
|
16839
16844
|
},
|
|
16840
|
-
meta
|
|
16845
|
+
meta,
|
|
16846
|
+
resolution
|
|
16841
16847
|
} = options;
|
|
16842
16848
|
if (width < 1 || !Number.isInteger(width)) {
|
|
16843
16849
|
throw new RangeError(`width must be an integer and at least 1. Received ${width}`);
|
|
@@ -16852,6 +16858,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
16852
16858
|
this.colorModel = colorModel;
|
|
16853
16859
|
this.origin = origin;
|
|
16854
16860
|
this.meta = meta;
|
|
16861
|
+
this.originalResolution = resolution;
|
|
16855
16862
|
const colorModelDef = colorModels[colorModel];
|
|
16856
16863
|
this.components = colorModelDef.components;
|
|
16857
16864
|
this.alpha = colorModelDef.alpha;
|
|
@@ -16872,6 +16879,38 @@ ${indent}columns: ${matrix.columns}
|
|
|
16872
16879
|
this.data = data;
|
|
16873
16880
|
}
|
|
16874
16881
|
}
|
|
16882
|
+
/**
|
|
16883
|
+
* Returns normalized resolution in pixels per centimeter. If resolution unit is unknown, return null.
|
|
16884
|
+
* @returns Object with x and y resolutions in pixel/cm.
|
|
16885
|
+
*/
|
|
16886
|
+
get normalizedResolution() {
|
|
16887
|
+
if (!this.originalResolution) {
|
|
16888
|
+
return undefined;
|
|
16889
|
+
}
|
|
16890
|
+
const centimetersPerInch = 2.54;
|
|
16891
|
+
const centimetersPerMeter = 100;
|
|
16892
|
+
switch (this.originalResolution.unit) {
|
|
16893
|
+
case 'inch':
|
|
16894
|
+
return {
|
|
16895
|
+
x: this.originalResolution.x / centimetersPerInch,
|
|
16896
|
+
y: this.originalResolution.y / centimetersPerInch
|
|
16897
|
+
};
|
|
16898
|
+
case 'centimeter':
|
|
16899
|
+
return {
|
|
16900
|
+
x: this.originalResolution.x,
|
|
16901
|
+
y: this.originalResolution.y
|
|
16902
|
+
};
|
|
16903
|
+
case 'meter':
|
|
16904
|
+
return {
|
|
16905
|
+
x: this.originalResolution.x / centimetersPerMeter,
|
|
16906
|
+
y: this.originalResolution.y / centimetersPerMeter
|
|
16907
|
+
};
|
|
16908
|
+
case 'unknown':
|
|
16909
|
+
return null;
|
|
16910
|
+
default:
|
|
16911
|
+
throw new Error('Unknown resolution unit.');
|
|
16912
|
+
}
|
|
16913
|
+
}
|
|
16875
16914
|
/**
|
|
16876
16915
|
* Create a new Image based on the properties of an existing one.
|
|
16877
16916
|
* @param other - Reference image.
|
|
@@ -28679,7 +28718,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
28679
28718
|
* @returns - The `fs`, `path` and `url` Node.js modules.
|
|
28680
28719
|
*/
|
|
28681
28720
|
function getNodeApiOrThrow(methodName) {
|
|
28682
|
-
if (
|
|
28721
|
+
if (!isNode()) {
|
|
28683
28722
|
throw new Error(`${methodName} is only implemented for Node.js`);
|
|
28684
28723
|
}
|
|
28685
28724
|
return {
|
|
@@ -28688,6 +28727,35 @@ ${indent}columns: ${matrix.columns}
|
|
|
28688
28727
|
url: process.getBuiltinModule('node:url')
|
|
28689
28728
|
};
|
|
28690
28729
|
}
|
|
28730
|
+
let CanvasCtorBrowser;
|
|
28731
|
+
let CanvasCtorNode;
|
|
28732
|
+
/**
|
|
28733
|
+
* Returns a 2D canvas context for rendering on the browser or Node.js.
|
|
28734
|
+
* @param width - Width of the canvas.
|
|
28735
|
+
* @param height - Height of the canvas.
|
|
28736
|
+
* @returns The initialised canvas context.
|
|
28737
|
+
*/
|
|
28738
|
+
function getCanvasContext(width, height) {
|
|
28739
|
+
if (isNode()) {
|
|
28740
|
+
CanvasCtorNode ??= getRequireFn()('skia-canvas').Canvas;
|
|
28741
|
+
return new CanvasCtorNode(width, height).getContext('2d');
|
|
28742
|
+
} else {
|
|
28743
|
+
CanvasCtorBrowser ??= globalThis.OffscreenCanvas;
|
|
28744
|
+
const context = new CanvasCtorBrowser(width, height).getContext('2d');
|
|
28745
|
+
if (!context) {
|
|
28746
|
+
throw new Error('Failed to create canvas context');
|
|
28747
|
+
}
|
|
28748
|
+
return context;
|
|
28749
|
+
}
|
|
28750
|
+
}
|
|
28751
|
+
function isNode() {
|
|
28752
|
+
return typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function';
|
|
28753
|
+
}
|
|
28754
|
+
let requireFn;
|
|
28755
|
+
function getRequireFn() {
|
|
28756
|
+
requireFn ??= process.getBuiltinModule('node:module').createRequire((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('image-js.umd.js', document.baseURI).href)));
|
|
28757
|
+
return requireFn;
|
|
28758
|
+
}
|
|
28691
28759
|
|
|
28692
28760
|
/**
|
|
28693
28761
|
* Asynchronously write an image to the disk.
|
|
@@ -28714,7 +28782,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
28714
28782
|
await nodeApi.fs.promises.writeFile(path, toWrite);
|
|
28715
28783
|
}
|
|
28716
28784
|
/**
|
|
28717
|
-
* Synchronous version of
|
|
28785
|
+
* Synchronous version of {@link write}.
|
|
28718
28786
|
* This method is only implemented for Node.js.
|
|
28719
28787
|
* @param path - Path where the image should be written.
|
|
28720
28788
|
* @param image - Image to save.
|
|
@@ -31517,10 +31585,23 @@ ${indent}columns: ${matrix.columns}
|
|
|
31517
31585
|
default:
|
|
31518
31586
|
throw new RangeError(`invalid number of channels: ${png.channels}`);
|
|
31519
31587
|
}
|
|
31588
|
+
let resolution;
|
|
31589
|
+
if (png.resolution) {
|
|
31590
|
+
resolution = png.resolution.unit === 1 ? /*If the resolution unit is meters*/{
|
|
31591
|
+
x: png.resolution.x,
|
|
31592
|
+
y: png.resolution.y,
|
|
31593
|
+
unit: 'meter'
|
|
31594
|
+
} : /*If resolution unit is unknown */{
|
|
31595
|
+
x: png.resolution.x,
|
|
31596
|
+
y: png.resolution.y,
|
|
31597
|
+
unit: 'unknown'
|
|
31598
|
+
};
|
|
31599
|
+
}
|
|
31520
31600
|
return new Image(png.width, png.height, {
|
|
31521
31601
|
colorModel,
|
|
31522
31602
|
bitDepth,
|
|
31523
|
-
data: png.data
|
|
31603
|
+
data: png.data,
|
|
31604
|
+
resolution
|
|
31524
31605
|
});
|
|
31525
31606
|
}
|
|
31526
31607
|
/**
|
|
@@ -31590,6 +31671,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
31590
31671
|
if (ifd.data instanceof Float32Array || ifd.data instanceof Float64Array) {
|
|
31591
31672
|
throw new Error('Float TIFF data is not supported.');
|
|
31592
31673
|
}
|
|
31674
|
+
const resolution = getTiffResolution(ifd);
|
|
31593
31675
|
if (ifd.type === 3) {
|
|
31594
31676
|
const hasAlpha = ifd.samplesPerPixel === 2;
|
|
31595
31677
|
const pixelLength = hasAlpha ? 4 : 3;
|
|
@@ -31617,7 +31699,8 @@ ${indent}columns: ${matrix.columns}
|
|
|
31617
31699
|
data,
|
|
31618
31700
|
colorModel: hasAlpha ? 'RGBA' : 'RGB',
|
|
31619
31701
|
bitDepth: 16,
|
|
31620
|
-
meta: getMetadata(ifd)
|
|
31702
|
+
meta: getMetadata(ifd),
|
|
31703
|
+
resolution
|
|
31621
31704
|
});
|
|
31622
31705
|
} else if (ifd.type === 1 || ifd.type === 0) {
|
|
31623
31706
|
if (ifd.bitsPerSample !== 1) {
|
|
@@ -31625,14 +31708,16 @@ ${indent}columns: ${matrix.columns}
|
|
|
31625
31708
|
data: ifd.data,
|
|
31626
31709
|
bitDepth: ifd.bitsPerSample,
|
|
31627
31710
|
colorModel: ifd.alpha ? 'GREYA' : 'GREY',
|
|
31628
|
-
meta: getMetadata(ifd)
|
|
31711
|
+
meta: getMetadata(ifd),
|
|
31712
|
+
resolution
|
|
31629
31713
|
});
|
|
31630
31714
|
} else {
|
|
31631
31715
|
return new Image(ifd.width, ifd.height, {
|
|
31632
31716
|
data: ifd.data.map(pixel => pixel * 255),
|
|
31633
31717
|
bitDepth: 8,
|
|
31634
31718
|
colorModel: 'GREY',
|
|
31635
|
-
meta: getMetadata(ifd)
|
|
31719
|
+
meta: getMetadata(ifd),
|
|
31720
|
+
resolution
|
|
31636
31721
|
});
|
|
31637
31722
|
}
|
|
31638
31723
|
} else {
|
|
@@ -31640,10 +31725,41 @@ ${indent}columns: ${matrix.columns}
|
|
|
31640
31725
|
data: ifd.data,
|
|
31641
31726
|
bitDepth: ifd.bitsPerSample,
|
|
31642
31727
|
colorModel: ifd.alpha ? 'RGBA' : 'RGB',
|
|
31643
|
-
meta: getMetadata(ifd)
|
|
31728
|
+
meta: getMetadata(ifd),
|
|
31729
|
+
resolution
|
|
31644
31730
|
});
|
|
31645
31731
|
}
|
|
31646
31732
|
}
|
|
31733
|
+
/**
|
|
31734
|
+
* Gets image resolution from its metadata and converts it into Pixels per meter, when it's possible. Also keeps original resolution values and units.
|
|
31735
|
+
* @param ifd - Tiff metadata.
|
|
31736
|
+
* @returns Resolution object.
|
|
31737
|
+
*/
|
|
31738
|
+
function getTiffResolution(ifd) {
|
|
31739
|
+
if (!ifd.xResolution || !ifd.yResolution) {
|
|
31740
|
+
return undefined;
|
|
31741
|
+
}
|
|
31742
|
+
switch (ifd.resolutionUnit) {
|
|
31743
|
+
case 1:
|
|
31744
|
+
return {
|
|
31745
|
+
x: ifd.xResolution,
|
|
31746
|
+
y: ifd.yResolution,
|
|
31747
|
+
unit: 'unknown'
|
|
31748
|
+
};
|
|
31749
|
+
case 3:
|
|
31750
|
+
return {
|
|
31751
|
+
x: ifd.xResolution,
|
|
31752
|
+
y: ifd.yResolution,
|
|
31753
|
+
unit: 'centimeter'
|
|
31754
|
+
};
|
|
31755
|
+
default:
|
|
31756
|
+
return {
|
|
31757
|
+
x: ifd.xResolution,
|
|
31758
|
+
y: ifd.yResolution,
|
|
31759
|
+
unit: 'inch'
|
|
31760
|
+
};
|
|
31761
|
+
}
|
|
31762
|
+
}
|
|
31647
31763
|
|
|
31648
31764
|
/**
|
|
31649
31765
|
* Decode input data. Data format is automatically detected.
|
|
@@ -31680,7 +31796,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
31680
31796
|
return decode(data);
|
|
31681
31797
|
}
|
|
31682
31798
|
/**
|
|
31683
|
-
* Synchronous version of
|
|
31799
|
+
* Synchronous version of {@link read}.
|
|
31684
31800
|
* This method is only implemented for Node.js.
|
|
31685
31801
|
* @param path - The path to the image.
|
|
31686
31802
|
* @returns Image instance.
|
|
@@ -32893,7 +33009,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
32893
33009
|
|
|
32894
33010
|
var priorityQueue = {exports: {}};
|
|
32895
33011
|
|
|
32896
|
-
(function (module, exports) {
|
|
33012
|
+
(function (module, exports$1) {
|
|
32897
33013
|
(function (f) {
|
|
32898
33014
|
{
|
|
32899
33015
|
module.exports = f();
|
|
@@ -32923,7 +33039,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
32923
33039
|
for (var o = 0; o < r.length; o++) s(r[o]);
|
|
32924
33040
|
return s;
|
|
32925
33041
|
}({
|
|
32926
|
-
1: [function (_dereq_, module, exports) {
|
|
33042
|
+
1: [function (_dereq_, module, exports$1) {
|
|
32927
33043
|
var AbstractPriorityQueue,
|
|
32928
33044
|
ArrayStrategy,
|
|
32929
33045
|
BHeapStrategy,
|
|
@@ -32968,7 +33084,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
32968
33084
|
"./PriorityQueue/BHeapStrategy": 4,
|
|
32969
33085
|
"./PriorityQueue/BinaryHeapStrategy": 5
|
|
32970
33086
|
}],
|
|
32971
|
-
2: [function (_dereq_, module, exports) {
|
|
33087
|
+
2: [function (_dereq_, module, exports$1) {
|
|
32972
33088
|
module.exports = function () {
|
|
32973
33089
|
function AbstractPriorityQueue(options) {
|
|
32974
33090
|
var ref;
|
|
@@ -33006,7 +33122,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
33006
33122
|
return AbstractPriorityQueue;
|
|
33007
33123
|
}();
|
|
33008
33124
|
}, {}],
|
|
33009
|
-
3: [function (_dereq_, module, exports) {
|
|
33125
|
+
3: [function (_dereq_, module, exports$1) {
|
|
33010
33126
|
var binarySearchForIndexReversed;
|
|
33011
33127
|
binarySearchForIndexReversed = function (array, value, comparator) {
|
|
33012
33128
|
var high, low, mid;
|
|
@@ -33049,7 +33165,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
33049
33165
|
return ArrayStrategy;
|
|
33050
33166
|
}();
|
|
33051
33167
|
}, {}],
|
|
33052
|
-
4: [function (_dereq_, module, exports) {
|
|
33168
|
+
4: [function (_dereq_, module, exports$1) {
|
|
33053
33169
|
module.exports = function () {
|
|
33054
33170
|
function BHeapStrategy(options) {
|
|
33055
33171
|
var arr, j, k, len, ref, ref1, shift, value;
|
|
@@ -33187,7 +33303,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
33187
33303
|
return BHeapStrategy;
|
|
33188
33304
|
}();
|
|
33189
33305
|
}, {}],
|
|
33190
|
-
5: [function (_dereq_, module, exports) {
|
|
33306
|
+
5: [function (_dereq_, module, exports$1) {
|
|
33191
33307
|
module.exports = function () {
|
|
33192
33308
|
function BinaryHeapStrategy(options) {
|
|
33193
33309
|
var ref;
|
|
@@ -33849,6 +33965,105 @@ ${indent}columns: ${matrix.columns}
|
|
|
33849
33965
|
BINARY: ['Mask']
|
|
33850
33966
|
};
|
|
33851
33967
|
|
|
33968
|
+
/**
|
|
33969
|
+
* Draws text on an image.
|
|
33970
|
+
* @param image - Image to write text on.
|
|
33971
|
+
* @param text - Text to write on the image.
|
|
33972
|
+
* @param options - Out Options
|
|
33973
|
+
* @returns Image with drawn text.
|
|
33974
|
+
*/
|
|
33975
|
+
function drawText(image, text, options) {
|
|
33976
|
+
if (Array.isArray(text) && text.length === 0) {
|
|
33977
|
+
throw new Error('At least one text element must be provided');
|
|
33978
|
+
}
|
|
33979
|
+
const newImage = getOutputImage(image, options, {
|
|
33980
|
+
clone: true
|
|
33981
|
+
});
|
|
33982
|
+
const defaultFont = options?.font ?? '12px Helvetica';
|
|
33983
|
+
const defaultColor = options?.fontColor ?? [255, 255, 255, 255];
|
|
33984
|
+
const ctx = getCanvasContext(image.width, image.height);
|
|
33985
|
+
if (!Array.isArray(text)) {
|
|
33986
|
+
drawTextElement(image, ctx, text, defaultFont, defaultColor);
|
|
33987
|
+
} else {
|
|
33988
|
+
for (const label of text) {
|
|
33989
|
+
drawTextElement(image, ctx, label, defaultFont, defaultColor);
|
|
33990
|
+
}
|
|
33991
|
+
}
|
|
33992
|
+
layerCanvas(newImage.getRawImage().data, ctx.getImageData(0, 0, image.width, image.height).data, image.channels, image.bitDepth);
|
|
33993
|
+
return newImage;
|
|
33994
|
+
}
|
|
33995
|
+
function drawTextElement(image, ctx, text, defaultFont, defaultColor) {
|
|
33996
|
+
ctx.font = text.font ?? defaultFont;
|
|
33997
|
+
const fontColor = text.fontColor ?? defaultColor;
|
|
33998
|
+
validateValues(fontColor, image);
|
|
33999
|
+
const alpha = fontColor[3] ? fontColor[3] / 255 : 1;
|
|
34000
|
+
const normalizedColor = [fontColor[0] ?? 0, fontColor[1] ?? 0, fontColor[2] ?? 0, alpha];
|
|
34001
|
+
ctx.fillStyle = `rgba(${normalizedColor.join(',')})`;
|
|
34002
|
+
ctx.fillText(String(text.content), text.position.column, text.position.row);
|
|
34003
|
+
}
|
|
34004
|
+
/**
|
|
34005
|
+
* Draws labels on the image data from canvas.
|
|
34006
|
+
* @param imageData - Image data to draw text on.
|
|
34007
|
+
* @param canvasData - Canvas data to draw on the image.
|
|
34008
|
+
* @param numberOfChannels - Number of channels of the initial image.
|
|
34009
|
+
* @param bitDepth - Bit depth of the initial image.
|
|
34010
|
+
*/
|
|
34011
|
+
function layerCanvas(imageData, canvasData, numberOfChannels, bitDepth) {
|
|
34012
|
+
const config = CHANNEL_CONFIGS[numberOfChannels] || CHANNEL_CONFIGS[1];
|
|
34013
|
+
const pixelCount = canvasData.length >>> 2;
|
|
34014
|
+
const bitShift = bitDepth - 8;
|
|
34015
|
+
let imageIndex = 0;
|
|
34016
|
+
let canvasIndex = 0;
|
|
34017
|
+
for (let pixel = 0; pixel < pixelCount; pixel++) {
|
|
34018
|
+
const canvasAlpha = canvasData[canvasIndex + 3] / 255;
|
|
34019
|
+
// Skip transparent canvas pixels completely
|
|
34020
|
+
if (canvasAlpha === 0) {
|
|
34021
|
+
imageIndex += numberOfChannels;
|
|
34022
|
+
canvasIndex += 4;
|
|
34023
|
+
continue;
|
|
34024
|
+
}
|
|
34025
|
+
const invAlpha = 1 - canvasAlpha;
|
|
34026
|
+
for (const channel of config.channelOffsets) {
|
|
34027
|
+
const targetIndex = imageIndex + channel;
|
|
34028
|
+
imageData[targetIndex] = Math.round(canvasData[canvasIndex + channel] * canvasAlpha + imageData[targetIndex] * invAlpha) << bitShift;
|
|
34029
|
+
}
|
|
34030
|
+
if (config.hasAlpha) {
|
|
34031
|
+
const alphaIndex = imageIndex + config.alphaOffset;
|
|
34032
|
+
const imageAlpha = (imageData[alphaIndex] >>> bitShift) / 255;
|
|
34033
|
+
const newAlpha = canvasAlpha + imageAlpha * (1 - canvasAlpha);
|
|
34034
|
+
imageData[alphaIndex] = Math.round(newAlpha * 255) << bitShift;
|
|
34035
|
+
}
|
|
34036
|
+
imageIndex += numberOfChannels;
|
|
34037
|
+
canvasIndex += 4;
|
|
34038
|
+
}
|
|
34039
|
+
}
|
|
34040
|
+
const CHANNEL_CONFIGS = {
|
|
34041
|
+
// GREY
|
|
34042
|
+
1: {
|
|
34043
|
+
channelOffsets: [0],
|
|
34044
|
+
hasAlpha: false,
|
|
34045
|
+
alphaOffset: undefined
|
|
34046
|
+
},
|
|
34047
|
+
// GREYA
|
|
34048
|
+
2: {
|
|
34049
|
+
channelOffsets: [0],
|
|
34050
|
+
hasAlpha: true,
|
|
34051
|
+
alphaOffset: 1
|
|
34052
|
+
},
|
|
34053
|
+
3: {
|
|
34054
|
+
// RGB
|
|
34055
|
+
channelOffsets: [0, 1, 2],
|
|
34056
|
+
hasAlpha: false,
|
|
34057
|
+
alphaOffset: undefined
|
|
34058
|
+
},
|
|
34059
|
+
4: {
|
|
34060
|
+
// RGBA
|
|
34061
|
+
channelOffsets: [0, 1, 2],
|
|
34062
|
+
hasAlpha: true,
|
|
34063
|
+
alphaOffset: 3
|
|
34064
|
+
}
|
|
34065
|
+
};
|
|
34066
|
+
|
|
33852
34067
|
exports.BorderType = BorderType;
|
|
33853
34068
|
exports.DerivativeFilter = DerivativeFilter;
|
|
33854
34069
|
exports.GreyAlgorithm = GreyAlgorithm;
|
|
@@ -33919,6 +34134,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
33919
34134
|
exports.drawPolylineOnImage = drawPolylineOnImage;
|
|
33920
34135
|
exports.drawPolylineOnMask = drawPolylineOnMask;
|
|
33921
34136
|
exports.drawRectangle = drawRectangle;
|
|
34137
|
+
exports.drawText = drawText;
|
|
33922
34138
|
exports.encode = encode;
|
|
33923
34139
|
exports.encodeDataURL = encodeDataURL;
|
|
33924
34140
|
exports.encodeJpeg = encodeJpeg;
|