@pallasoft/ps-file-components 1.5.0 → 2.0.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/components/ps-document-scanner-loader.d.ts +1 -1
- package/dist/components/ps-document-scanner-sheet.d.ts +1 -1
- package/dist/components/ps-document-scanner-sheet.js +40 -110
- package/dist/components/ps-document-scanner.d.ts +1 -1
- package/dist/components/ps-document-scanner.js +2 -3
- package/dist/components/ps-scan-camera-view.d.ts +2 -9
- package/dist/components/ps-scan-camera-view.js +3 -12
- package/dist/components/ps-scan-crop-editor.d.ts +4 -4
- package/dist/components/ps-scan-crop-editor.js +9 -9
- package/dist/components/ps-scan-permission-view.d.ts +2 -3
- package/dist/components/ps-scan-permission-view.js +2 -2
- package/dist/components/ps-scan-photo-button.d.ts +2 -3
- package/dist/components/ps-scan-photo-button.js +5 -5
- package/dist/components/ps-scan-preview.d.ts +12 -0
- package/dist/components/ps-scan-preview.js +10 -0
- package/dist/components/ps-scan-shutter.d.ts +1 -2
- package/dist/components/ps-scan-shutter.js +1 -1
- package/dist/constants/ps-document-scanner-labels.d.ts +5 -34
- package/dist/constants/ps-document-scanner-labels.js +5 -34
- package/dist/constants/ps-scan-chrome-classes.d.ts +0 -2
- package/dist/constants/ps-scan-chrome-classes.js +0 -2
- package/dist/constants/ps-scan-config.d.ts +24 -31
- package/dist/constants/ps-scan-config.js +24 -31
- package/dist/constants/ps-scan-step.d.ts +1 -1
- package/dist/constants/ps-scan-step.js +1 -1
- package/dist/esm/components/ps-document-scanner-sheet.js +41 -111
- package/dist/esm/components/ps-document-scanner.js +2 -3
- package/dist/esm/components/ps-scan-camera-view.js +3 -12
- package/dist/esm/components/ps-scan-crop-editor.js +9 -9
- package/dist/esm/components/ps-scan-permission-view.js +2 -2
- package/dist/esm/components/ps-scan-photo-button.js +5 -5
- package/dist/esm/components/ps-scan-preview.js +6 -0
- package/dist/esm/components/ps-scan-shutter.js +1 -1
- package/dist/esm/constants/ps-document-scanner-labels.js +5 -34
- package/dist/esm/constants/ps-scan-chrome-classes.js +0 -2
- package/dist/esm/constants/ps-scan-config.js +24 -31
- package/dist/esm/constants/ps-scan-step.js +1 -1
- package/dist/esm/hooks/use-ps-scan-live-detection.js +17 -21
- package/dist/esm/hooks/use-ps-scan-photo.js +42 -0
- package/dist/esm/index.js +0 -2
- package/dist/esm/services/ps-scan-camera-service.js +2 -2
- package/dist/esm/services/ps-scan-canny-service.js +93 -0
- package/dist/esm/services/ps-scan-canvas-service.js +7 -1
- package/dist/esm/services/ps-scan-edge-service.js +73 -137
- package/dist/esm/services/ps-scan-file-name-service.js +2 -11
- package/dist/esm/services/ps-scan-geometry-service.js +36 -0
- package/dist/esm/services/ps-scan-hull-service.js +0 -39
- package/dist/esm/services/ps-scan-image-filter-service.js +0 -21
- package/dist/esm/services/ps-scan-morphology-service.js +44 -0
- package/dist/esm/services/ps-scan-pipeline-service.js +9 -19
- package/dist/esm/services/ps-scan-polygon-service.js +75 -0
- package/dist/esm/services/ps-scan-region-service.js +52 -0
- package/dist/esm/services/ps-scan-stability-service.js +9 -22
- package/dist/esm/services/ps-scan-warp-service.js +8 -2
- package/dist/esm/services/ps-scan-yield-service.js +5 -0
- package/dist/hooks/use-ps-scan-live-detection.d.ts +1 -1
- package/dist/hooks/use-ps-scan-live-detection.js +16 -20
- package/dist/hooks/use-ps-scan-photo.d.ts +9 -0
- package/dist/hooks/use-ps-scan-photo.js +46 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/models/ps-document-scanner-props.d.ts +0 -4
- package/dist/models/ps-document-scanner-sheet-props.d.ts +0 -4
- package/dist/models/ps-scan-gradient.d.ts +4 -0
- package/dist/models/ps-scan-live-detection.d.ts +0 -1
- package/dist/models/ps-scan-located.d.ts +5 -0
- package/dist/models/ps-scan-photo.d.ts +9 -0
- package/dist/models/ps-scan-region.d.ts +5 -0
- package/dist/models/ps-scan-result.d.ts +6 -0
- package/dist/models/ps-scan-stability.d.ts +0 -3
- package/dist/services/ps-scan-camera-service.js +2 -2
- package/dist/services/ps-scan-canny-service.d.ts +7 -0
- package/dist/services/ps-scan-canny-service.js +97 -0
- package/dist/services/ps-scan-canvas-service.js +7 -1
- package/dist/services/ps-scan-edge-service.d.ts +5 -5
- package/dist/services/ps-scan-edge-service.js +73 -137
- package/dist/services/ps-scan-file-name-service.d.ts +1 -3
- package/dist/services/ps-scan-file-name-service.js +2 -11
- package/dist/services/ps-scan-geometry-service.d.ts +2 -0
- package/dist/services/ps-scan-geometry-service.js +36 -0
- package/dist/services/ps-scan-hull-service.d.ts +0 -2
- package/dist/services/ps-scan-hull-service.js +0 -39
- package/dist/services/ps-scan-image-filter-service.d.ts +0 -1
- package/dist/services/ps-scan-image-filter-service.js +0 -21
- package/dist/services/ps-scan-morphology-service.d.ts +7 -0
- package/dist/services/ps-scan-morphology-service.js +48 -0
- package/dist/services/ps-scan-pipeline-service.d.ts +2 -5
- package/dist/services/ps-scan-pipeline-service.js +9 -19
- package/dist/services/ps-scan-polygon-service.d.ts +8 -0
- package/dist/services/ps-scan-polygon-service.js +79 -0
- package/dist/services/ps-scan-region-service.d.ts +4 -0
- package/dist/services/ps-scan-region-service.js +56 -0
- package/dist/services/ps-scan-stability-service.d.ts +1 -3
- package/dist/services/ps-scan-stability-service.js +9 -22
- package/dist/services/ps-scan-warp-service.d.ts +1 -1
- package/dist/services/ps-scan-warp-service.js +8 -2
- package/dist/services/ps-scan-yield-service.d.ts +3 -0
- package/dist/services/ps-scan-yield-service.js +9 -0
- package/package.json +1 -1
- package/dist/components/ps-scan-page-list.d.ts +0 -14
- package/dist/components/ps-scan-page-list.js +0 -22
- package/dist/components/ps-scan-page-stack.d.ts +0 -7
- package/dist/components/ps-scan-page-stack.js +0 -6
- package/dist/components/ps-scan-review.d.ts +0 -24
- package/dist/components/ps-scan-review.js +0 -37
- package/dist/constants/ps-scan-filter.d.ts +0 -7
- package/dist/constants/ps-scan-filter.js +0 -9
- package/dist/constants/ps-scan-output-format.d.ts +0 -5
- package/dist/constants/ps-scan-output-format.js +0 -7
- package/dist/esm/components/ps-scan-page-list.js +0 -18
- package/dist/esm/components/ps-scan-page-stack.js +0 -2
- package/dist/esm/components/ps-scan-review.js +0 -33
- package/dist/esm/constants/ps-scan-filter.js +0 -6
- package/dist/esm/constants/ps-scan-output-format.js +0 -4
- package/dist/esm/hooks/use-ps-scan-pages.js +0 -62
- package/dist/esm/hooks/use-ps-scan-previews.js +0 -57
- package/dist/esm/services/ps-scan-enhance-service.js +0 -97
- package/dist/esm/services/ps-scan-order-service.js +0 -13
- package/dist/esm/services/ps-scan-output-service.js +0 -24
- package/dist/esm/services/ps-scan-pdf-service.js +0 -56
- package/dist/hooks/use-ps-scan-pages.d.ts +0 -12
- package/dist/hooks/use-ps-scan-pages.js +0 -66
- package/dist/hooks/use-ps-scan-previews.d.ts +0 -2
- package/dist/hooks/use-ps-scan-previews.js +0 -61
- package/dist/models/ps-scan-added-page.d.ts +0 -5
- package/dist/models/ps-scan-levels.d.ts +0 -4
- package/dist/models/ps-scan-output-options.d.ts +0 -7
- package/dist/models/ps-scan-page.d.ts +0 -12
- package/dist/models/ps-scan-pdf-page.d.ts +0 -5
- package/dist/services/ps-scan-enhance-service.d.ts +0 -9
- package/dist/services/ps-scan-enhance-service.js +0 -101
- package/dist/services/ps-scan-order-service.d.ts +0 -4
- package/dist/services/ps-scan-order-service.js +0 -17
- package/dist/services/ps-scan-output-service.d.ts +0 -5
- package/dist/services/ps-scan-output-service.js +0 -28
- package/dist/services/ps-scan-pdf-service.d.ts +0 -5
- package/dist/services/ps-scan-pdf-service.js +0 -60
- /package/dist/esm/models/{ps-scan-added-page.js → ps-scan-gradient.js} +0 -0
- /package/dist/esm/models/{ps-scan-levels.js → ps-scan-located.js} +0 -0
- /package/dist/esm/models/{ps-scan-output-options.js → ps-scan-photo.js} +0 -0
- /package/dist/esm/models/{ps-scan-page.js → ps-scan-region.js} +0 -0
- /package/dist/esm/models/{ps-scan-pdf-page.js → ps-scan-result.js} +0 -0
- /package/dist/models/{ps-scan-added-page.js → ps-scan-gradient.js} +0 -0
- /package/dist/models/{ps-scan-levels.js → ps-scan-located.js} +0 -0
- /package/dist/models/{ps-scan-output-options.js → ps-scan-photo.js} +0 -0
- /package/dist/models/{ps-scan-page.js → ps-scan-region.js} +0 -0
- /package/dist/models/{ps-scan-pdf-page.js → ps-scan-result.js} +0 -0
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import { PsScanConfig } from '../constants/ps-scan-config';
|
|
1
2
|
import { PsScanHomographyService } from './ps-scan-homography-service';
|
|
2
3
|
import { PsScanRasterService } from './ps-scan-raster-service';
|
|
4
|
+
import { PsScanYieldService } from './ps-scan-yield-service';
|
|
3
5
|
export class PsScanWarpService {
|
|
4
|
-
static warp(source, pixelQuad, width, height) {
|
|
6
|
+
static async warp(source, pixelQuad, width, height) {
|
|
5
7
|
const matrix = PsScanHomographyService.fromUnitSquare(pixelQuad);
|
|
6
8
|
const target = PsScanRasterService.create(width, height);
|
|
7
9
|
const spanX = Math.max(1, width - 1);
|
|
8
10
|
const spanY = Math.max(1, height - 1);
|
|
9
|
-
|
|
11
|
+
const rowsPerChunk = Math.max(1, Math.floor(PsScanConfig.warpChunkPixels / width));
|
|
12
|
+
for (let y = 0; y < height; y += 1) {
|
|
10
13
|
for (let x = 0; x < width; x += 1) {
|
|
11
14
|
const point = PsScanHomographyService.apply(matrix, x / spanX, y / spanY);
|
|
12
15
|
PsScanWarpService.sample(source, point.x, point.y, target.data, (y * width + x) * 4);
|
|
13
16
|
}
|
|
17
|
+
if ((y + 1) % rowsPerChunk === 0)
|
|
18
|
+
await PsScanYieldService.next();
|
|
19
|
+
}
|
|
14
20
|
return target;
|
|
15
21
|
}
|
|
16
22
|
static sample(source, x, y, out, at) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
import type { PsScanLiveDetection } from '../models/ps-scan-live-detection';
|
|
3
|
-
export declare const usePsScanLiveDetection: (videoRef: RefObject<HTMLVideoElement | null>, isActive: boolean
|
|
3
|
+
export declare const usePsScanLiveDetection: (videoRef: RefObject<HTMLVideoElement | null>, isActive: boolean) => PsScanLiveDetection;
|
|
@@ -6,43 +6,39 @@ const ps_scan_config_1 = require("../constants/ps-scan-config");
|
|
|
6
6
|
const ps_scan_canvas_service_1 = require("../services/ps-scan-canvas-service");
|
|
7
7
|
const ps_scan_edge_service_1 = require("../services/ps-scan-edge-service");
|
|
8
8
|
const ps_scan_stability_service_1 = require("../services/ps-scan-stability-service");
|
|
9
|
-
const usePsScanLiveDetection = (videoRef, isActive
|
|
10
|
-
const [detection, setDetection] = (0, react_1.useState)({
|
|
11
|
-
const isAutoRef = (0, react_1.useRef)(isAuto);
|
|
12
|
-
const onSteadyRef = (0, react_1.useRef)(onSteady);
|
|
13
|
-
isAutoRef.current = isAuto;
|
|
14
|
-
onSteadyRef.current = onSteady;
|
|
9
|
+
const usePsScanLiveDetection = (videoRef, isActive) => {
|
|
10
|
+
const [detection, setDetection] = (0, react_1.useState)({ quad: null });
|
|
15
11
|
(0, react_1.useEffect)(() => {
|
|
16
12
|
if (!isActive) {
|
|
17
|
-
setDetection({
|
|
13
|
+
setDetection({ quad: null });
|
|
18
14
|
return;
|
|
19
15
|
}
|
|
16
|
+
let isCancelled = false;
|
|
20
17
|
let state = ps_scan_stability_service_1.PsScanStabilityService.initial();
|
|
21
|
-
let last = performance.now();
|
|
22
18
|
let timer;
|
|
23
|
-
const tick = () => {
|
|
19
|
+
const tick = async () => {
|
|
24
20
|
const video = videoRef.current;
|
|
25
|
-
const now = performance.now();
|
|
26
21
|
if (video !== null && video.videoWidth > 0 && document.visibilityState === 'visible') {
|
|
27
22
|
try {
|
|
28
23
|
const raster = ps_scan_canvas_service_1.PsScanCanvasService.sample(video, ps_scan_config_1.PsScanConfig.liveDetectMaxDimension);
|
|
29
|
-
|
|
24
|
+
const quad = await ps_scan_edge_service_1.PsScanEdgeService.detect(raster, ps_scan_config_1.PsScanConfig.liveDetectMaxDimension);
|
|
25
|
+
if (isCancelled)
|
|
26
|
+
return;
|
|
27
|
+
state = ps_scan_stability_service_1.PsScanStabilityService.next(state, quad);
|
|
30
28
|
}
|
|
31
29
|
catch {
|
|
32
30
|
state = ps_scan_stability_service_1.PsScanStabilityService.initial();
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
setDetection({ progress, quad: state.quad });
|
|
36
|
-
if (progress >= 1) {
|
|
37
|
-
state = ps_scan_stability_service_1.PsScanStabilityService.disarm(state);
|
|
38
|
-
onSteadyRef.current();
|
|
39
|
-
}
|
|
32
|
+
setDetection((current) => (current.quad === state.quad ? current : { quad: state.quad }));
|
|
40
33
|
}
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
if (!isCancelled)
|
|
35
|
+
timer = setTimeout(tick, ps_scan_config_1.PsScanConfig.liveDetectIntervalMs);
|
|
43
36
|
};
|
|
44
37
|
timer = setTimeout(tick, ps_scan_config_1.PsScanConfig.liveDetectIntervalMs);
|
|
45
|
-
return () =>
|
|
38
|
+
return () => {
|
|
39
|
+
isCancelled = true;
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
};
|
|
46
42
|
}, [isActive]);
|
|
47
43
|
return detection;
|
|
48
44
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PsScanPhoto } from '../models/ps-scan-photo';
|
|
2
|
+
import type { PsScanQuad } from '../models/ps-scan-quad';
|
|
3
|
+
export declare const usePsScanPhoto: () => {
|
|
4
|
+
clear: () => void;
|
|
5
|
+
detectAgain: () => Promise<boolean>;
|
|
6
|
+
load: (source: Blob) => Promise<PsScanPhoto>;
|
|
7
|
+
photo: PsScanPhoto | null;
|
|
8
|
+
setCorners: (corners: PsScanQuad) => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePsScanPhoto = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const ps_scan_pipeline_service_1 = require("../services/ps-scan-pipeline-service");
|
|
6
|
+
const usePsScanPhoto = () => {
|
|
7
|
+
const [photo, setPhoto] = (0, react_1.useState)(null);
|
|
8
|
+
const url = (0, react_1.useRef)('');
|
|
9
|
+
const release = (0, react_1.useCallback)(() => {
|
|
10
|
+
if (url.current !== '')
|
|
11
|
+
URL.revokeObjectURL(url.current);
|
|
12
|
+
url.current = '';
|
|
13
|
+
}, []);
|
|
14
|
+
(0, react_1.useEffect)(() => release, [release]);
|
|
15
|
+
const load = (0, react_1.useCallback)(async (source) => {
|
|
16
|
+
const prepared = await ps_scan_pipeline_service_1.PsScanPipelineService.prepare(source);
|
|
17
|
+
const next = {
|
|
18
|
+
corners: prepared.corners,
|
|
19
|
+
height: prepared.height,
|
|
20
|
+
isDetected: prepared.isDetected,
|
|
21
|
+
source,
|
|
22
|
+
sourceUrl: URL.createObjectURL(source),
|
|
23
|
+
width: prepared.width,
|
|
24
|
+
};
|
|
25
|
+
release();
|
|
26
|
+
url.current = next.sourceUrl;
|
|
27
|
+
setPhoto(next);
|
|
28
|
+
return next;
|
|
29
|
+
}, [release]);
|
|
30
|
+
const setCorners = (0, react_1.useCallback)((corners) => setPhoto((current) => (current === null ? current : { ...current, corners })), []);
|
|
31
|
+
const detectAgain = (0, react_1.useCallback)(async () => {
|
|
32
|
+
if (photo === null)
|
|
33
|
+
return false;
|
|
34
|
+
const prepared = await ps_scan_pipeline_service_1.PsScanPipelineService.prepare(photo.source);
|
|
35
|
+
setPhoto((current) => current === null
|
|
36
|
+
? current
|
|
37
|
+
: { ...current, corners: prepared.corners, isDetected: prepared.isDetected });
|
|
38
|
+
return prepared.isDetected;
|
|
39
|
+
}, [photo]);
|
|
40
|
+
const clear = (0, react_1.useCallback)(() => {
|
|
41
|
+
release();
|
|
42
|
+
setPhoto(null);
|
|
43
|
+
}, [release]);
|
|
44
|
+
return { clear, detectAgain, load, photo, setCorners };
|
|
45
|
+
};
|
|
46
|
+
exports.usePsScanPhoto = usePsScanPhoto;
|
package/dist/index.d.ts
CHANGED
|
@@ -71,7 +71,5 @@ export * from './hooks/use-ps-in-view';
|
|
|
71
71
|
export * from './hooks/use-ps-upload-queue';
|
|
72
72
|
export * from './components/ps-document-scanner';
|
|
73
73
|
export * from './constants/ps-document-scanner-labels';
|
|
74
|
-
export * from './constants/ps-scan-filter';
|
|
75
|
-
export * from './constants/ps-scan-output-format';
|
|
76
74
|
export * from './models/ps-document-scanner-props';
|
|
77
75
|
export * from './models/ps-file-picker-scan';
|
package/dist/index.js
CHANGED
|
@@ -87,7 +87,5 @@ __exportStar(require("./hooks/use-ps-in-view"), exports);
|
|
|
87
87
|
__exportStar(require("./hooks/use-ps-upload-queue"), exports);
|
|
88
88
|
__exportStar(require("./components/ps-document-scanner"), exports);
|
|
89
89
|
__exportStar(require("./constants/ps-document-scanner-labels"), exports);
|
|
90
|
-
__exportStar(require("./constants/ps-scan-filter"), exports);
|
|
91
|
-
__exportStar(require("./constants/ps-scan-output-format"), exports);
|
|
92
90
|
__exportStar(require("./models/ps-document-scanner-props"), exports);
|
|
93
91
|
__exportStar(require("./models/ps-file-picker-scan"), exports);
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { PsDocumentScannerLabels } from '../constants/ps-document-scanner-labels';
|
|
2
|
-
import type { PsScanOutputFormat } from '../constants/ps-scan-output-format';
|
|
3
2
|
import type { PsLabelSet } from './ps-label-set';
|
|
4
3
|
export interface PsDocumentScannerProps {
|
|
5
4
|
className?: string;
|
|
6
5
|
fileName?: string;
|
|
7
|
-
isAutoCapture?: boolean;
|
|
8
6
|
isOpen: boolean;
|
|
9
7
|
jpegQuality?: number;
|
|
10
8
|
labels?: Partial<PsLabelSet<typeof PsDocumentScannerLabels>>;
|
|
11
9
|
maxDimension?: number;
|
|
12
|
-
maxPages?: number;
|
|
13
10
|
onClose: () => void;
|
|
14
11
|
onComplete: (files: File[]) => void;
|
|
15
|
-
outputFormat?: PsScanOutputFormat;
|
|
16
12
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import type { PsDocumentScannerLabels } from '../constants/ps-document-scanner-labels';
|
|
2
|
-
import type { PsScanOutputFormat } from '../constants/ps-scan-output-format';
|
|
3
2
|
import type { PsLabelSet } from './ps-label-set';
|
|
4
3
|
export interface PsDocumentScannerSheetProps {
|
|
5
4
|
fileName: string;
|
|
6
|
-
isAutoCapture: boolean;
|
|
7
5
|
jpegQuality: number;
|
|
8
6
|
labels: PsLabelSet<typeof PsDocumentScannerLabels>;
|
|
9
7
|
maxDimension: number;
|
|
10
|
-
maxPages: number;
|
|
11
8
|
onClose: () => void;
|
|
12
9
|
onComplete: (files: File[]) => void;
|
|
13
|
-
outputFormat: PsScanOutputFormat;
|
|
14
10
|
}
|
|
@@ -54,8 +54,8 @@ class PsScanCameraService {
|
|
|
54
54
|
audio: false,
|
|
55
55
|
video: {
|
|
56
56
|
facingMode: { ideal: 'environment' },
|
|
57
|
-
height: { ideal:
|
|
58
|
-
width: { ideal:
|
|
57
|
+
height: { ideal: 2160 },
|
|
58
|
+
width: { ideal: 3840 },
|
|
59
59
|
},
|
|
60
60
|
});
|
|
61
61
|
const track = stream.getVideoTracks()[0];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsScanCannyService = void 0;
|
|
4
|
+
const ps_scan_config_1 = require("../constants/ps-scan-config");
|
|
5
|
+
class PsScanCannyService {
|
|
6
|
+
static edges(gray, width, height) {
|
|
7
|
+
const gradient = PsScanCannyService.gradient(gray, width, height);
|
|
8
|
+
const ridges = PsScanCannyService.suppress(gradient, width, height);
|
|
9
|
+
const high = PsScanCannyService.highThreshold(ridges);
|
|
10
|
+
return PsScanCannyService.hysteresis(ridges, width, height, high * ps_scan_config_1.PsScanConfig.cannyLowRatio, high);
|
|
11
|
+
}
|
|
12
|
+
static gradient(gray, width, height) {
|
|
13
|
+
const magnitude = new Float32Array(width * height);
|
|
14
|
+
const direction = new Uint8Array(width * height);
|
|
15
|
+
for (let y = 1; y < height - 1; y += 1)
|
|
16
|
+
for (let x = 1; x < width - 1; x += 1) {
|
|
17
|
+
const i = y * width + x;
|
|
18
|
+
const gx = -gray[i - width - 1] +
|
|
19
|
+
gray[i - width + 1] -
|
|
20
|
+
2 * gray[i - 1] +
|
|
21
|
+
2 * gray[i + 1] -
|
|
22
|
+
gray[i + width - 1] +
|
|
23
|
+
gray[i + width + 1];
|
|
24
|
+
const gy = -gray[i - width - 1] -
|
|
25
|
+
2 * gray[i - width] -
|
|
26
|
+
gray[i - width + 1] +
|
|
27
|
+
gray[i + width - 1] +
|
|
28
|
+
2 * gray[i + width] +
|
|
29
|
+
gray[i + width + 1];
|
|
30
|
+
const ax = Math.abs(gx);
|
|
31
|
+
const ay = Math.abs(gy);
|
|
32
|
+
magnitude[i] = Math.hypot(gx, gy) / 4;
|
|
33
|
+
if (ay <= ax * 0.41421356)
|
|
34
|
+
direction[i] = 0;
|
|
35
|
+
else if (ay >= ax * 2.41421356)
|
|
36
|
+
direction[i] = 2;
|
|
37
|
+
else
|
|
38
|
+
direction[i] = gx * gy > 0 ? 1 : 3;
|
|
39
|
+
}
|
|
40
|
+
return { direction, magnitude };
|
|
41
|
+
}
|
|
42
|
+
static highThreshold(ridges) {
|
|
43
|
+
const values = [];
|
|
44
|
+
for (let index = 0; index < ridges.length; index += 1)
|
|
45
|
+
if (ridges[index] > 0)
|
|
46
|
+
values.push(ridges[index]);
|
|
47
|
+
if (values.length === 0)
|
|
48
|
+
return ps_scan_config_1.PsScanConfig.cannyMinHigh;
|
|
49
|
+
values.sort((a, b) => a - b);
|
|
50
|
+
const at = Math.min(values.length - 1, Math.floor(values.length * ps_scan_config_1.PsScanConfig.cannyHighPercentile));
|
|
51
|
+
return Math.max(ps_scan_config_1.PsScanConfig.cannyMinHigh, values[at]);
|
|
52
|
+
}
|
|
53
|
+
static hysteresis(ridges, width, height, low, high) {
|
|
54
|
+
const out = new Uint8Array(width * height);
|
|
55
|
+
const stack = [];
|
|
56
|
+
for (let index = 0; index < ridges.length; index += 1)
|
|
57
|
+
if (ridges[index] >= high) {
|
|
58
|
+
out[index] = 1;
|
|
59
|
+
stack.push(index);
|
|
60
|
+
}
|
|
61
|
+
while (stack.length > 0) {
|
|
62
|
+
const index = stack.pop();
|
|
63
|
+
if (index === undefined)
|
|
64
|
+
break;
|
|
65
|
+
const x = index % width;
|
|
66
|
+
const y = (index - x) / width;
|
|
67
|
+
for (let dy = -1; dy <= 1; dy += 1)
|
|
68
|
+
for (let dx = -1; dx <= 1; dx += 1) {
|
|
69
|
+
const nx = x + dx;
|
|
70
|
+
const ny = y + dy;
|
|
71
|
+
if (nx < 0 || ny < 0 || nx >= width || ny >= height)
|
|
72
|
+
continue;
|
|
73
|
+
const next = ny * width + nx;
|
|
74
|
+
if (out[next] === 0 && ridges[next] >= low) {
|
|
75
|
+
out[next] = 1;
|
|
76
|
+
stack.push(next);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
static suppress(gradient, width, height) {
|
|
83
|
+
const { direction, magnitude } = gradient;
|
|
84
|
+
const out = new Float32Array(width * height);
|
|
85
|
+
const offsets = [1, width + 1, width, width - 1];
|
|
86
|
+
for (let y = 1; y < height - 1; y += 1)
|
|
87
|
+
for (let x = 1; x < width - 1; x += 1) {
|
|
88
|
+
const i = y * width + x;
|
|
89
|
+
const offset = offsets[direction[i]];
|
|
90
|
+
const value = magnitude[i];
|
|
91
|
+
if (value >= magnitude[i - offset] && value > magnitude[i + offset])
|
|
92
|
+
out[i] = value;
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.PsScanCannyService = PsScanCannyService;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsScanCanvasService = void 0;
|
|
4
|
+
const ps_scan_config_1 = require("../constants/ps-scan-config");
|
|
4
5
|
const ps_scan_geometry_service_1 = require("./ps-scan-geometry-service");
|
|
5
6
|
class PsScanCanvasService {
|
|
6
7
|
static async decode(blob, maxDimension) {
|
|
7
8
|
const bitmap = await createImageBitmap(blob, { imageOrientation: 'from-image' });
|
|
8
|
-
const
|
|
9
|
+
const capped = ps_scan_geometry_service_1.PsScanGeometryService.fitWithin({ height: bitmap.height, width: bitmap.width }, maxDimension);
|
|
10
|
+
const shrink = Math.min(1, Math.sqrt(ps_scan_config_1.PsScanConfig.decodeMaxPixels / (capped.width * capped.height)));
|
|
11
|
+
const size = {
|
|
12
|
+
height: Math.max(1, Math.round(capped.height * shrink)),
|
|
13
|
+
width: Math.max(1, Math.round(capped.width * shrink)),
|
|
14
|
+
};
|
|
9
15
|
const context = PsScanCanvasService.context(size.width, size.height);
|
|
10
16
|
context.drawImage(bitmap, 0, 0, size.width, size.height);
|
|
11
17
|
const naturalHeight = bitmap.height;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import type { PsScanLocated } from '../models/ps-scan-located';
|
|
1
2
|
import type { PsScanQuad } from '../models/ps-scan-quad';
|
|
2
3
|
import type { PsScanRaster } from '../models/ps-scan-raster';
|
|
3
4
|
export declare class PsScanEdgeService {
|
|
4
|
-
static detect(source: PsScanRaster): PsScanQuad | null
|
|
5
|
-
|
|
6
|
-
private static
|
|
7
|
-
private static
|
|
8
|
-
private static threshold;
|
|
5
|
+
static detect(source: PsScanRaster, maxDimension: number): Promise<PsScanQuad | null>;
|
|
6
|
+
static locate(source: PsScanRaster, maxDimension: number): Promise<PsScanLocated>;
|
|
7
|
+
private static candidate;
|
|
8
|
+
private static normalise;
|
|
9
9
|
}
|