label-printer 0.5.4 → 0.6.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/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +149 -97
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -762,7 +762,7 @@ declare class Image extends LabelField {
|
|
|
762
762
|
* @param height
|
|
763
763
|
* @returns
|
|
764
764
|
*/
|
|
765
|
-
static create(image: string, x: number, y: number, width?: number, height?: number): Promise<Image>;
|
|
765
|
+
static create(image: string | Blob, x: number, y: number, width?: number, height?: number): Promise<Image>;
|
|
766
766
|
}
|
|
767
767
|
|
|
768
768
|
declare class QRCode extends LabelField {
|
package/dist/index.d.ts
CHANGED
|
@@ -762,7 +762,7 @@ declare class Image extends LabelField {
|
|
|
762
762
|
* @param height
|
|
763
763
|
* @returns
|
|
764
764
|
*/
|
|
765
|
-
static create(image: string, x: number, y: number, width?: number, height?: number): Promise<Image>;
|
|
765
|
+
static create(image: string | Blob, x: number, y: number, width?: number, height?: number): Promise<Image>;
|
|
766
766
|
}
|
|
767
767
|
|
|
768
768
|
declare class QRCode extends LabelField {
|
package/dist/index.js
CHANGED
|
@@ -22,9 +22,9 @@ var __spreadValues = (a, b) => {
|
|
|
22
22
|
return a;
|
|
23
23
|
};
|
|
24
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
-
var __export = (
|
|
25
|
+
var __export = (target2, all) => {
|
|
26
26
|
for (var name in all)
|
|
27
|
-
__defProp(
|
|
27
|
+
__defProp(target2, name, { get: all[name], enumerable: true });
|
|
28
28
|
};
|
|
29
29
|
var __copyProps = (to, from, except, desc) => {
|
|
30
30
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -34,12 +34,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
34
34
|
}
|
|
35
35
|
return to;
|
|
36
36
|
};
|
|
37
|
-
var __toESM = (mod, isNodeMode,
|
|
37
|
+
var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
38
38
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
39
39
|
// file that has been converted to a CommonJS file using a Babel-
|
|
40
40
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
41
41
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
42
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(
|
|
42
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target2, "default", { value: mod, enumerable: true }) : target2,
|
|
43
43
|
mod
|
|
44
44
|
));
|
|
45
45
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
@@ -424,14 +424,15 @@ var ImageProcessor = class {
|
|
|
424
424
|
/**
|
|
425
425
|
* Get pixel information about an image
|
|
426
426
|
* @param image Image to process (local file path, remote URL, data URL, or Blob)
|
|
427
|
+
* @param target Optional target raster size. Useful for vector inputs (e.g. SVG) to rasterize at the final size.
|
|
427
428
|
* @returns Promise with image data including width, height, pixel data, and bits per pixel
|
|
428
429
|
*/
|
|
429
|
-
static getImageData(image2) {
|
|
430
|
+
static getImageData(image2, target2) {
|
|
430
431
|
return __async(this, null, function* () {
|
|
431
432
|
if (typeof window !== "undefined") {
|
|
432
|
-
return this.getImageDataBrowser(image2);
|
|
433
|
+
return this.getImageDataBrowser(image2, target2);
|
|
433
434
|
} else {
|
|
434
|
-
return this.getImageDataNode(image2);
|
|
435
|
+
return this.getImageDataNode(image2, target2);
|
|
435
436
|
}
|
|
436
437
|
});
|
|
437
438
|
}
|
|
@@ -439,74 +440,76 @@ var ImageProcessor = class {
|
|
|
439
440
|
/**
|
|
440
441
|
* Get pixel information about an image in browser environment
|
|
441
442
|
* @param image Image to process
|
|
443
|
+
* @param target Optional target raster size.
|
|
442
444
|
* @returns Promise with image data
|
|
443
445
|
*/
|
|
444
|
-
static getImageDataBrowser(image2) {
|
|
446
|
+
static getImageDataBrowser(image2, target2) {
|
|
445
447
|
return __async(this, null, function* () {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
}
|
|
471
|
-
};
|
|
472
|
-
img.onerror = () => reject(new Error("Failed to load image"));
|
|
473
|
-
if (typeof image2 === "string") {
|
|
474
|
-
img.src = image2;
|
|
475
|
-
} else {
|
|
476
|
-
const url2 = URL.createObjectURL(image2);
|
|
477
|
-
img.onload = () => {
|
|
478
|
-
URL.revokeObjectURL(url2);
|
|
479
|
-
resolve({
|
|
480
|
-
data: new Uint8Array(0),
|
|
481
|
-
// Will be set by the actual onload
|
|
482
|
-
width: 0,
|
|
483
|
-
height: 0,
|
|
484
|
-
bitsPerPixel: 4
|
|
485
|
-
});
|
|
486
|
-
};
|
|
487
|
-
img.src = url2;
|
|
448
|
+
var _a, _b;
|
|
449
|
+
const loadImage = (src2) => {
|
|
450
|
+
return new Promise((resolve, reject) => {
|
|
451
|
+
const img = new Image();
|
|
452
|
+
img.crossOrigin = "anonymous";
|
|
453
|
+
img.onload = () => resolve(img);
|
|
454
|
+
img.onerror = () => reject(new Error("Failed to load image"));
|
|
455
|
+
img.src = src2;
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
let src;
|
|
459
|
+
let revokeUrl;
|
|
460
|
+
if (typeof image2 === "string") {
|
|
461
|
+
src = this.normalizePotentialSVGSource(image2);
|
|
462
|
+
} else {
|
|
463
|
+
revokeUrl = URL.createObjectURL(image2);
|
|
464
|
+
src = revokeUrl;
|
|
465
|
+
}
|
|
466
|
+
try {
|
|
467
|
+
const img = yield loadImage(src);
|
|
468
|
+
const canvas = document.createElement("canvas");
|
|
469
|
+
const ctx = canvas.getContext("2d");
|
|
470
|
+
if (!ctx) {
|
|
471
|
+
throw new Error("Could not get canvas context");
|
|
488
472
|
}
|
|
489
|
-
|
|
473
|
+
const width = (_a = target2 == null ? void 0 : target2.width) != null ? _a : img.width;
|
|
474
|
+
const height = (_b = target2 == null ? void 0 : target2.height) != null ? _b : img.height;
|
|
475
|
+
canvas.width = width;
|
|
476
|
+
canvas.height = height;
|
|
477
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
478
|
+
const imageData2 = ctx.getImageData(0, 0, width, height);
|
|
479
|
+
return {
|
|
480
|
+
data: new Uint8Array(imageData2.data),
|
|
481
|
+
width,
|
|
482
|
+
height,
|
|
483
|
+
bitsPerPixel: 4
|
|
484
|
+
};
|
|
485
|
+
} finally {
|
|
486
|
+
if (revokeUrl) URL.revokeObjectURL(revokeUrl);
|
|
487
|
+
}
|
|
490
488
|
});
|
|
491
489
|
}
|
|
492
490
|
/******** NODEJS ********/
|
|
493
491
|
/**
|
|
494
492
|
* Get pixel information about an image in Node.js environment
|
|
495
493
|
* @param image Image to process
|
|
494
|
+
* @param target Optional target raster size.
|
|
496
495
|
* @returns Promise with image data
|
|
497
496
|
*/
|
|
498
|
-
static getImageDataNode(image2) {
|
|
497
|
+
static getImageDataNode(image2, _target) {
|
|
499
498
|
return __async(this, null, function* () {
|
|
500
499
|
console.log("Processing image in Node.js environment");
|
|
501
500
|
if (image2 instanceof Blob) {
|
|
502
501
|
throw new Error("Blob input not supported in Node.js environment. Use file path or data URL instead.");
|
|
503
502
|
}
|
|
503
|
+
const trimmed = image2.trim();
|
|
504
|
+
if (trimmed.startsWith("<svg")) {
|
|
505
|
+
return this.rasterizeSVGNode(trimmed, _target);
|
|
506
|
+
}
|
|
504
507
|
if (image2.startsWith("data:")) {
|
|
505
|
-
return this.getImageFromData(image2);
|
|
508
|
+
return this.getImageFromData(image2, _target);
|
|
506
509
|
} else if (image2.startsWith("http://") || image2.startsWith("https://")) {
|
|
507
|
-
return this.getImageFromUrl(image2);
|
|
510
|
+
return this.getImageFromUrl(image2, _target);
|
|
508
511
|
} else {
|
|
509
|
-
return this.getImageFromFile(image2);
|
|
512
|
+
return this.getImageFromFile(image2, _target);
|
|
510
513
|
}
|
|
511
514
|
});
|
|
512
515
|
}
|
|
@@ -515,7 +518,7 @@ var ImageProcessor = class {
|
|
|
515
518
|
* @param dataURL Data URL string
|
|
516
519
|
* @returns Promise with image data
|
|
517
520
|
*/
|
|
518
|
-
static getImageFromData(dataURL) {
|
|
521
|
+
static getImageFromData(dataURL, target2) {
|
|
519
522
|
return __async(this, null, function* () {
|
|
520
523
|
var _a;
|
|
521
524
|
const [header, data] = dataURL.split(",");
|
|
@@ -523,8 +526,13 @@ var ImageProcessor = class {
|
|
|
523
526
|
if (!(mimeType == null ? void 0 : mimeType.startsWith("image/"))) {
|
|
524
527
|
throw new Error("Invalid image data URL");
|
|
525
528
|
}
|
|
526
|
-
const buffer2 = Buffer.from(data, "base64");
|
|
527
529
|
const extension = mimeType.split("/")[1].toLowerCase();
|
|
530
|
+
if (extension === "svg+xml" || mimeType === "image/svg+xml") {
|
|
531
|
+
const isBase64 = header.includes(";base64");
|
|
532
|
+
const svgText = isBase64 ? Buffer.from(data, "base64").toString("utf8") : decodeURIComponent(data);
|
|
533
|
+
return this.rasterizeSVGNode(svgText, target2);
|
|
534
|
+
}
|
|
535
|
+
const buffer2 = Buffer.from(data, "base64");
|
|
528
536
|
return this.parse(buffer2, extension);
|
|
529
537
|
});
|
|
530
538
|
}
|
|
@@ -533,7 +541,7 @@ var ImageProcessor = class {
|
|
|
533
541
|
* @param image
|
|
534
542
|
* @returns
|
|
535
543
|
*/
|
|
536
|
-
static getImageFromFile(image) {
|
|
544
|
+
static getImageFromFile(image, target) {
|
|
537
545
|
return __async(this, null, function* () {
|
|
538
546
|
const fs = yield eval("require")("fs");
|
|
539
547
|
const path = yield eval("require")("path");
|
|
@@ -542,6 +550,10 @@ var ImageProcessor = class {
|
|
|
542
550
|
}
|
|
543
551
|
const buffer = fs.readFileSync(image);
|
|
544
552
|
const ext = path.extname(image).toLowerCase();
|
|
553
|
+
if (ext === ".svg") {
|
|
554
|
+
const svgText = buffer.toString("utf8");
|
|
555
|
+
return this.rasterizeSVGNode(svgText, target);
|
|
556
|
+
}
|
|
545
557
|
return this.parse(buffer, ext);
|
|
546
558
|
});
|
|
547
559
|
}
|
|
@@ -550,16 +562,16 @@ var ImageProcessor = class {
|
|
|
550
562
|
* @param url Remote image URL
|
|
551
563
|
* @returns Promise with image data
|
|
552
564
|
*/
|
|
553
|
-
static getImageFromUrl(url2) {
|
|
565
|
+
static getImageFromUrl(url2, target2) {
|
|
554
566
|
return __async(this, null, function* () {
|
|
555
567
|
let fetch;
|
|
556
568
|
try {
|
|
557
569
|
fetch = globalThis.fetch;
|
|
558
570
|
} catch (e) {
|
|
559
|
-
return this.fetchWithHttps(url2);
|
|
571
|
+
return this.fetchWithHttps(url2, target2);
|
|
560
572
|
}
|
|
561
573
|
if (!fetch) {
|
|
562
|
-
return this.fetchWithHttps(url2);
|
|
574
|
+
return this.fetchWithHttps(url2, target2);
|
|
563
575
|
}
|
|
564
576
|
const response = yield fetch(url2);
|
|
565
577
|
if (!response.ok) {
|
|
@@ -569,6 +581,10 @@ var ImageProcessor = class {
|
|
|
569
581
|
const buffer2 = Buffer.from(arrayBuffer);
|
|
570
582
|
const contentType = response.headers.get("content-type");
|
|
571
583
|
const imageType = this.getImageType(contentType || "", url2);
|
|
584
|
+
if (imageType === "svg") {
|
|
585
|
+
const svgText = buffer2.toString("utf8");
|
|
586
|
+
return this.rasterizeSVGNode(svgText, target2);
|
|
587
|
+
}
|
|
572
588
|
return this.parse(buffer2, imageType);
|
|
573
589
|
});
|
|
574
590
|
}
|
|
@@ -577,7 +593,7 @@ var ImageProcessor = class {
|
|
|
577
593
|
* @param url Remote image URL
|
|
578
594
|
* @returns Promise with image data
|
|
579
595
|
*/
|
|
580
|
-
static fetchWithHttps(url) {
|
|
596
|
+
static fetchWithHttps(url, target) {
|
|
581
597
|
return __async(this, null, function* () {
|
|
582
598
|
const https = yield eval("require")("https");
|
|
583
599
|
const http = yield eval("require")("http");
|
|
@@ -597,8 +613,12 @@ var ImageProcessor = class {
|
|
|
597
613
|
const buffer2 = Buffer.concat(chunks);
|
|
598
614
|
const contentType = response.headers["content-type"] || "";
|
|
599
615
|
const imageType = this.getImageType(contentType || "", url);
|
|
600
|
-
|
|
601
|
-
|
|
616
|
+
if (imageType === "svg") {
|
|
617
|
+
const svgText = buffer2.toString("utf8");
|
|
618
|
+
resolve(this.rasterizeSVGNode(svgText, target));
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
resolve(this.parse(buffer2, imageType));
|
|
602
622
|
} catch (error) {
|
|
603
623
|
reject(error);
|
|
604
624
|
}
|
|
@@ -626,6 +646,8 @@ var ImageProcessor = class {
|
|
|
626
646
|
return "png";
|
|
627
647
|
} else if (contentType.includes("jpeg") || contentType.includes("jpg")) {
|
|
628
648
|
return "jpeg";
|
|
649
|
+
} else if (contentType.includes("svg")) {
|
|
650
|
+
return "svg";
|
|
629
651
|
}
|
|
630
652
|
}
|
|
631
653
|
const urlLower = url2.toLowerCase();
|
|
@@ -633,32 +655,57 @@ var ImageProcessor = class {
|
|
|
633
655
|
return "png";
|
|
634
656
|
} else if (urlLower.includes(".jpg") || urlLower.includes(".jpeg")) {
|
|
635
657
|
return "jpeg";
|
|
658
|
+
} else if (urlLower.includes(".svg")) {
|
|
659
|
+
return "svg";
|
|
636
660
|
}
|
|
637
661
|
return "";
|
|
638
662
|
}
|
|
639
663
|
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
* @param extension
|
|
643
|
-
* @returns
|
|
644
|
-
*/
|
|
664
|
+
* Parse image data by extension
|
|
665
|
+
*/
|
|
645
666
|
static parse(buffer2, extension) {
|
|
646
|
-
|
|
647
|
-
|
|
667
|
+
const normalizedExtension = extension.startsWith(".") ? extension.slice(1) : extension;
|
|
668
|
+
console.log(`Parsing image with extension: ${normalizedExtension}`);
|
|
669
|
+
if (normalizedExtension === "png") {
|
|
648
670
|
return parsePNG(buffer2);
|
|
649
|
-
} else if (
|
|
671
|
+
} else if (normalizedExtension === "jpeg" || normalizedExtension === "jpg") {
|
|
650
672
|
return this.parseJPEG(buffer2);
|
|
673
|
+
} else if (normalizedExtension === "svg") {
|
|
674
|
+
throw new Error("svg-not-supported-in-node");
|
|
651
675
|
} else {
|
|
652
|
-
throw new Error(`Unsupported image format: ${
|
|
676
|
+
throw new Error(`Unsupported image format: ${normalizedExtension}. Supported formats: PNG, JPEG`);
|
|
653
677
|
}
|
|
654
678
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
679
|
+
static rasterizeSVGNode(svg, target) {
|
|
680
|
+
let Resvg;
|
|
681
|
+
try {
|
|
682
|
+
Resvg = eval("require")("@resvg/resvg-js").Resvg;
|
|
683
|
+
} catch (_e) {
|
|
684
|
+
throw new Error("svg-rasterizer-missing");
|
|
685
|
+
}
|
|
686
|
+
const fitTo = target ? { mode: "width", value: target.width } : void 0;
|
|
687
|
+
const resvg = new Resvg(svg, {
|
|
688
|
+
fitTo
|
|
689
|
+
});
|
|
690
|
+
const pngData = resvg.render().asPng();
|
|
691
|
+
const pngBuffer = Buffer.from(pngData);
|
|
692
|
+
const imageData = parsePNG(pngBuffer);
|
|
693
|
+
if (target && (imageData.width !== target.width || imageData.height !== target.height)) {
|
|
694
|
+
return this.resize(imageData, target.width, target.height);
|
|
695
|
+
}
|
|
696
|
+
return imageData;
|
|
697
|
+
}
|
|
698
|
+
static normalizePotentialSVGSource(source) {
|
|
699
|
+
const trimmed = source.trim();
|
|
700
|
+
const isInlineSvg = trimmed.startsWith("<svg");
|
|
701
|
+
const isSvgDataUrl = trimmed.startsWith("data:image/svg+xml");
|
|
702
|
+
if (isInlineSvg) {
|
|
703
|
+
const encoded = encodeURIComponent(trimmed);
|
|
704
|
+
return `data:image/svg+xml;charset=utf-8,${encoded}`;
|
|
705
|
+
}
|
|
706
|
+
if (isSvgDataUrl) return source;
|
|
707
|
+
return source;
|
|
708
|
+
}
|
|
662
709
|
static parseJPEG(buffer2) {
|
|
663
710
|
if (buffer2[0] !== 255 || buffer2[1] !== 216) {
|
|
664
711
|
throw new Error("Invalid JPEG file");
|
|
@@ -725,8 +772,8 @@ var ImageProcessor = class {
|
|
|
725
772
|
* @param imageData Original image data
|
|
726
773
|
* @returns Grayscale image data
|
|
727
774
|
*/
|
|
728
|
-
static toGrayscale(
|
|
729
|
-
const { data, width, height } =
|
|
775
|
+
static toGrayscale(imageData2) {
|
|
776
|
+
const { data, width, height } = imageData2;
|
|
730
777
|
const grayscaleData = new Uint8Array(data.length);
|
|
731
778
|
for (let i = 0; i < data.length; i += 4) {
|
|
732
779
|
const r = data[i];
|
|
@@ -743,7 +790,7 @@ var ImageProcessor = class {
|
|
|
743
790
|
data: grayscaleData,
|
|
744
791
|
width,
|
|
745
792
|
height,
|
|
746
|
-
bitsPerPixel:
|
|
793
|
+
bitsPerPixel: imageData2.bitsPerPixel
|
|
747
794
|
};
|
|
748
795
|
}
|
|
749
796
|
/**
|
|
@@ -753,8 +800,8 @@ var ImageProcessor = class {
|
|
|
753
800
|
* @param newHeight Target height
|
|
754
801
|
* @returns Resized image data
|
|
755
802
|
*/
|
|
756
|
-
static resize(
|
|
757
|
-
const { data, width, height, bitsPerPixel } =
|
|
803
|
+
static resize(imageData2, newWidth, newHeight) {
|
|
804
|
+
const { data, width, height, bitsPerPixel } = imageData2;
|
|
758
805
|
const resizedData = new Uint8Array(newWidth * newHeight * bitsPerPixel);
|
|
759
806
|
const xRatio = width / newWidth;
|
|
760
807
|
const yRatio = height / newHeight;
|
|
@@ -782,15 +829,17 @@ var ImageProcessor_default = ImageProcessor;
|
|
|
782
829
|
// src/helpers/ImageUtils.ts
|
|
783
830
|
var BLACK_PIXEL = 0;
|
|
784
831
|
var WHITE_PIXEL = 1;
|
|
832
|
+
var DEFAULT_THRESHOLD = 200;
|
|
785
833
|
var ImageUtils = class {
|
|
786
834
|
/**
|
|
787
835
|
* Get pixel information about an image
|
|
788
836
|
* @param image Image to process
|
|
837
|
+
* @param target Optional target raster size. Useful for vector inputs (e.g. SVG) to rasterize at the final size.
|
|
789
838
|
* @returns
|
|
790
839
|
*/
|
|
791
|
-
static getPixels(image2) {
|
|
840
|
+
static getPixels(image2, target2) {
|
|
792
841
|
return __async(this, null, function* () {
|
|
793
|
-
return yield ImageProcessor_default.getImageData(image2);
|
|
842
|
+
return yield ImageProcessor_default.getImageData(image2, target2);
|
|
794
843
|
});
|
|
795
844
|
}
|
|
796
845
|
/**
|
|
@@ -810,7 +859,10 @@ var ImageUtils = class {
|
|
|
810
859
|
width,
|
|
811
860
|
height,
|
|
812
861
|
bitsPerPixel
|
|
813
|
-
} = yield this.getPixels(
|
|
862
|
+
} = yield this.getPixels(
|
|
863
|
+
image2,
|
|
864
|
+
destinationWidth != null && destinationHeight != null ? { width: destinationWidth, height: destinationHeight } : void 0
|
|
865
|
+
);
|
|
814
866
|
const dim = getSizePreserveAspect(width, height, destinationWidth, destinationHeight);
|
|
815
867
|
const dWidth = dim.width;
|
|
816
868
|
const dHeight = dim.height;
|
|
@@ -826,16 +878,16 @@ var ImageUtils = class {
|
|
|
826
878
|
const r = data[baseIndex];
|
|
827
879
|
const g = data[baseIndex + 1];
|
|
828
880
|
const b = data[baseIndex + 2];
|
|
829
|
-
const a = data[baseIndex + 3];
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
837
|
-
} else {
|
|
881
|
+
const a = bitsPerPixel > 3 ? data[baseIndex + 3] : 255;
|
|
882
|
+
const alpha = a / 255;
|
|
883
|
+
const rC = r * alpha + 255 * (1 - alpha);
|
|
884
|
+
const gC = g * alpha + 255 * (1 - alpha);
|
|
885
|
+
const bC = b * alpha + 255 * (1 - alpha);
|
|
886
|
+
const luminance = 0.299 * rC + 0.587 * gC + 0.114 * bC;
|
|
887
|
+
if (luminance > DEFAULT_THRESHOLD) {
|
|
838
888
|
bitmapData[destinationIndex] = WHITE_PIXEL;
|
|
889
|
+
} else {
|
|
890
|
+
bitmapData[destinationIndex] = BLACK_PIXEL;
|
|
839
891
|
}
|
|
840
892
|
destinationIndex += 1;
|
|
841
893
|
}
|