scanic 0.1.7 β 1.0.2
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/README.md +163 -86
- package/dist/scanic.js +622 -498
- package/dist/scanic.js.map +1 -1
- package/dist/scanic.umd.cjs +1 -1
- package/dist/scanic.umd.cjs.map +1 -1
- package/package.json +16 -4
package/README.md
CHANGED
|
@@ -11,49 +11,58 @@
|
|
|
11
11
|
<a href="https://npmjs.com/package/scanic"><img src="https://badgen.net/npm/v/scanic"></a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
# Scanic
|
|
14
|
+
# Scanic πβ‘
|
|
15
15
|
|
|
16
|
-
**
|
|
16
|
+
**Ultra-fast, production-ready document scanning for the modern Web.**
|
|
17
17
|
|
|
18
|
-
Scanic is a
|
|
18
|
+
Scanic is a high-performance document scanner library that brings professional-grade document edge detection and perspective correction to the browser and Node.js. By combining **Rust-powered WebAssembly** for pixel crunching and **GPU-accelerated Canvas** for image warping, Scanic delivers near-native performance (~10ms transforms) with a tiny footprint.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
---
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## π Why Scanic?
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Traditional web scanning solutions often force a trade-off:
|
|
25
|
+
- **OpenCV.js**: Powerful, but requires a massive **30MB+** download.
|
|
26
|
+
- **Pure JS**: Lightweight, but struggles with real-time performance and complex transforms.
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
**Scanic bridges this gap:**
|
|
29
|
+
- **Hybrid Engine**: Rust/WASM handles the CPU-heavy edge detection.
|
|
30
|
+
- **Turbo Warp**: Custom Triangle Subdivision algorithm utilizes the GPU for perspective correction.
|
|
31
|
+
- **Zero Latency**: Designed for real-time applications like webcam scanning.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
---
|
|
29
34
|
|
|
30
|
-
## Features
|
|
35
|
+
## β¨ Features
|
|
31
36
|
|
|
32
|
-
-
|
|
33
|
-
- β‘ **
|
|
34
|
-
- π¦ **
|
|
35
|
-
- π οΈ **
|
|
36
|
-
-
|
|
37
|
-
-
|
|
37
|
+
- π― **Pinpoint Accuracy**: Robust document contour detection even in low-contrast environments.
|
|
38
|
+
- β‘ **Turbocharged Warp**: Perspective transforms in **< 10ms** (vs 500ms+ in standard loops).
|
|
39
|
+
- π¦ **WASM Core**: High-performance Gaussian Blur, Canny Edge Detection, and Dilation.
|
|
40
|
+
- π οΈ **Modern API**: Clean, Promise-based API with full **TypeScript** support.
|
|
41
|
+
- π¦ **Featherweight**: Under **100KB** total size (gzipped).
|
|
42
|
+
- π§ͺ **Production Grade**: Built-in regression tests with physical image baselines.
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
---
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
## Installation
|
|
46
|
+
## π οΈ Installation
|
|
44
47
|
|
|
45
48
|
```bash
|
|
49
|
+
# via npm
|
|
46
50
|
npm install scanic
|
|
47
|
-
```
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
# via yarn
|
|
53
|
+
yarn add scanic
|
|
54
|
+
```
|
|
50
55
|
|
|
56
|
+
### CDN
|
|
51
57
|
```html
|
|
52
58
|
<script src="https://unpkg.com/scanic/dist/scanic.js"></script>
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
---
|
|
56
62
|
|
|
63
|
+
## π Usage
|
|
64
|
+
|
|
65
|
+
### Simple Usage
|
|
57
66
|
```js
|
|
58
67
|
import { scanDocument, extractDocument } from 'scanic';
|
|
59
68
|
|
|
@@ -68,17 +77,25 @@ const extracted = await scanDocument(imageElement, { mode: 'extract' });
|
|
|
68
77
|
if (extracted.success) {
|
|
69
78
|
document.body.appendChild(extracted.output); // Display extracted document
|
|
70
79
|
}
|
|
80
|
+
```
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
### Optimized Usage (Recommended for Batch/Real-time)
|
|
83
|
+
The `Scanner` class maintains a persistent WebAssembly instance, avoiding the overhead of re-initializing WASM for every scan.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { Scanner } from 'scanic';
|
|
87
|
+
|
|
88
|
+
const scanner = new Scanner();
|
|
89
|
+
|
|
90
|
+
// Initialize once (optional, scan() will initialize if needed)
|
|
91
|
+
await scanner.initialize();
|
|
92
|
+
|
|
93
|
+
// Scan multiple images efficiently
|
|
94
|
+
async function onFrame(img) {
|
|
95
|
+
const result = await scanner.scan(img, { mode: 'extract' });
|
|
96
|
+
if (result.success) {
|
|
97
|
+
// Process result...
|
|
98
|
+
}
|
|
82
99
|
}
|
|
83
100
|
```
|
|
84
101
|
|
|
@@ -121,37 +138,50 @@ async function processDocument() {
|
|
|
121
138
|
// <div id="output"></div>
|
|
122
139
|
```
|
|
123
140
|
|
|
124
|
-
## API Reference
|
|
125
|
-
|
|
126
|
-
###
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
141
|
+
## βοΈ API Reference
|
|
142
|
+
|
|
143
|
+
### `scanDocument(image, options?)`
|
|
144
|
+
The primary function for detecting and extracting documents.
|
|
145
|
+
|
|
146
|
+
| Parameter | Type | Description |
|
|
147
|
+
| :--- | :--- | :--- |
|
|
148
|
+
| `image` | `HTMLImage\|Canvas\|ImageData` | The source image to scan. |
|
|
149
|
+
| `options` | `Object` | Configuration options (see below). |
|
|
150
|
+
|
|
151
|
+
#### `options` Properties
|
|
152
|
+
| Option | Type | Default | Description |
|
|
153
|
+
| :--- | :--- | :--- | :--- |
|
|
154
|
+
| `mode` | `'detect' \| 'extract'` | `'detect'` | `'detect'` returns coordinates; `'extract'` returns the warped image. |
|
|
155
|
+
| `output` | `'canvas' \| 'imagedata' \| 'dataurl'` | `'canvas'` | The format of the returned processed image. |
|
|
156
|
+
| `maxProcessingDimension` | `number` | `800` | Downscales image to this size for detection (faster). |
|
|
157
|
+
| `lowThreshold` | `number` | `75` | Lower threshold for Canny edge detection. |
|
|
158
|
+
| `highThreshold` | `number` | `200` | Upper threshold for Canny edge detection. |
|
|
159
|
+
| `minArea` | `number` | `1000` | Minimum pixel area to consider a contour a "document". |
|
|
160
|
+
| `debug` | `boolean` | `false` | If true, returns intermediate processing steps. |
|
|
161
|
+
|
|
162
|
+
#### Return Value
|
|
163
|
+
Returns a `Promise<ScannerResult>`:
|
|
164
|
+
```ts
|
|
165
|
+
{
|
|
166
|
+
success: boolean; // Did we find a document?
|
|
167
|
+
corners: CornerPoints; // { topLeft, topRight, bottomRight, bottomLeft }
|
|
168
|
+
output: any; // The warped image (if mode is 'extract')
|
|
169
|
+
contour: Array<Point>; // Raw detection points
|
|
170
|
+
timings: Array<Object>; // Performance breakdown
|
|
171
|
+
message: string; // Status or error message
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### `new Scanner()`
|
|
178
|
+
The recommended class for high-performance applications (Webcam, Batch processing).
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
const scanner = new Scanner();
|
|
182
|
+
await scanner.initialize(); // Pre-loads WASM
|
|
183
|
+
const result = await scanner.scan(image, options);
|
|
184
|
+
```
|
|
155
185
|
|
|
156
186
|
## Examples
|
|
157
187
|
|
|
@@ -195,15 +225,18 @@ const rawData = await scanDocument(imageElement, {
|
|
|
195
225
|
|
|
196
226
|
```
|
|
197
227
|
|
|
198
|
-
## Framework Examples
|
|
228
|
+
## π» Framework Examples
|
|
199
229
|
|
|
230
|
+
Scanic is framework-agnostic but works great with modern UI libraries:
|
|
200
231
|
|
|
201
|
-
|
|
232
|
+
| Framework | Link |
|
|
233
|
+
| :--- | :--- |
|
|
234
|
+
| **Vue 3** | [Vue.js Example & Guide](docs/vue-example.md) |
|
|
235
|
+
| **React** | [React Example & Guide](docs/react-example.md) |
|
|
202
236
|
|
|
203
|
-
|
|
237
|
+
---
|
|
204
238
|
|
|
205
|
-
|
|
206
|
-
## Development
|
|
239
|
+
## π οΈ Development
|
|
207
240
|
|
|
208
241
|
Clone the repository and set up the development environment:
|
|
209
242
|
|
|
@@ -237,8 +270,48 @@ npm run build:wasm
|
|
|
237
270
|
|
|
238
271
|
This uses Docker to build the WASM module without requiring local Rust installation.
|
|
239
272
|
|
|
273
|
+
### Testing
|
|
240
274
|
|
|
241
|
-
|
|
275
|
+
Scanic uses Vitest for unit and regression testing. We test against real document images to ensure detection accuracy remains consistent.
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npm test
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
## π₯οΈ Node.js Support
|
|
283
|
+
|
|
284
|
+
Scanic can run on the server! Since it relies on the Canvas API, you need to provide a canvas implementation (like `node-canvas`) and a DOM environment (`jsdom`).
|
|
285
|
+
|
|
286
|
+
```js
|
|
287
|
+
import { scanDocument } from 'scanic';
|
|
288
|
+
import { loadImage } from 'canvas';
|
|
289
|
+
import { JSDOM } from 'jsdom';
|
|
290
|
+
|
|
291
|
+
// Setup global environment
|
|
292
|
+
const dom = new JSDOM();
|
|
293
|
+
global.document = dom.window.document;
|
|
294
|
+
global.ImageData = dom.window.ImageData;
|
|
295
|
+
|
|
296
|
+
const img = await loadImage('document.jpg');
|
|
297
|
+
const result = await scanDocument(img, { mode: 'extract' });
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## π Comparison
|
|
303
|
+
|
|
304
|
+
| Feature | Scanic | jscanify | OpenCV.js |
|
|
305
|
+
| :--- | :--- | :--- | :--- |
|
|
306
|
+
| **Download Size** | **~100KB** | ~1MB | ~30MB |
|
|
307
|
+
| **Perspective Speed** | **~10ms** | ~200ms | ~5ms |
|
|
308
|
+
| **WASM Optimized** | β
Yes | β No | β
Yes |
|
|
309
|
+
| **GPU Acceleration** | β
Yes | β No | β No |
|
|
310
|
+
| **TypeScript** | β
Yes | β No | β
Yes |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## ποΈ Performance Architecture
|
|
242
315
|
|
|
243
316
|
Scanic uses a **hybrid JavaScript + WebAssembly approach**:
|
|
244
317
|
|
|
@@ -250,20 +323,25 @@ Scanic uses a **hybrid JavaScript + WebAssembly approach**:
|
|
|
250
323
|
- Non-maximum suppression for edge thinning
|
|
251
324
|
- Morphological operations (dilation/erosion)
|
|
252
325
|
|
|
253
|
-
## Contributing
|
|
326
|
+
## π€ Contributing
|
|
327
|
+
|
|
328
|
+
Contributions are welcome! Whether it's reporting a bug, suggesting a feature, or submitting a pull request, your help is appreciated.
|
|
329
|
+
|
|
330
|
+
1. **Report Issues**: Use the GitHub Issue tracker.
|
|
331
|
+
2. **Pull Requests**:
|
|
332
|
+
- Fork the repository.
|
|
333
|
+
- Create a feature branch.
|
|
334
|
+
- Commit your changes.
|
|
335
|
+
- Open a Pull Request.
|
|
336
|
+
|
|
337
|
+
---
|
|
254
338
|
|
|
255
|
-
|
|
339
|
+
## π Credits
|
|
256
340
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
3. **Pull Requests**: Ready to contribute code?
|
|
260
|
-
- Fork the repository
|
|
261
|
-
- Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
262
|
-
- Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
263
|
-
- Push to the branch (`git push origin feature/amazing-feature`)
|
|
264
|
-
- Open a Pull Request
|
|
341
|
+
- Inspired by [jscanify](https://github.com/puffinsoft/jscanify).
|
|
342
|
+
- WASM Blur module powered by Rust.
|
|
265
343
|
|
|
266
|
-
|
|
344
|
+
---
|
|
267
345
|
|
|
268
346
|
## π Sponsors
|
|
269
347
|
|
|
@@ -306,15 +384,14 @@ Please ensure your code follows the existing style.
|
|
|
306
384
|
|
|
307
385
|
</div>
|
|
308
386
|
|
|
309
|
-
## Roadmap
|
|
387
|
+
## πΊοΈ Roadmap
|
|
310
388
|
|
|
311
|
-
- [
|
|
389
|
+
- [x] TypeScript definitions
|
|
390
|
+
- [x] High-performance perspective transformation (Triangle Subdivision)
|
|
312
391
|
- [ ] Enhanced WASM module with additional Rust-optimized algorithms
|
|
313
|
-
- [ ] SIMD vectorization for more image processing operations
|
|
314
|
-
- [ ] TypeScript definitions
|
|
315
|
-
- [ ] Additional image enhancement filters
|
|
316
|
-
- [ ] Mobile-optimized processing
|
|
317
392
|
- [ ] WebGPU acceleration for supported browsers
|
|
393
|
+
- [ ] Mobile-optimized real-time video processing frames
|
|
394
|
+
- [ ] Additional image enhancement filters (Adaptive Thresholding, B&W)
|
|
318
395
|
|
|
319
396
|
## License
|
|
320
397
|
|