@areb0s/ocr-browser 1.0.0 → 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/build/ImageRaw.d.ts +25 -3
- package/build/ImageRaw.js +206 -65
- package/build/ImageRaw.js.map +1 -1
- package/package.json +3 -3
- package/src/ImageRaw.ts +240 -79
package/build/ImageRaw.d.ts
CHANGED
|
@@ -19,46 +19,68 @@ export declare class ImageRaw extends ImageRawBase {
|
|
|
19
19
|
* Check if the input is an HTMLVideoElement
|
|
20
20
|
*/
|
|
21
21
|
static isHTMLVideoElement(input: unknown): input is HTMLVideoElement;
|
|
22
|
+
/**
|
|
23
|
+
* Check if the input is an OffscreenCanvas
|
|
24
|
+
*/
|
|
25
|
+
static isOffscreenCanvas(input: unknown): input is OffscreenCanvas;
|
|
22
26
|
/**
|
|
23
27
|
* Check if the input is ImageRawData
|
|
24
28
|
*/
|
|
25
29
|
static isImageRawData(input: unknown): input is ImageRawData;
|
|
26
30
|
/**
|
|
27
31
|
* Universal factory method that accepts all browser image input types
|
|
28
|
-
*
|
|
32
|
+
* Works in both main thread and Web Worker
|
|
33
|
+
* @param input - URL string, ImageRawData, ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, or HTMLVideoElement
|
|
29
34
|
* @returns Promise<ImageRaw>
|
|
30
35
|
*/
|
|
31
|
-
static from(input: BrowserImageInput): Promise<ImageRaw>;
|
|
36
|
+
static from(input: BrowserImageInput | OffscreenCanvas): Promise<ImageRaw>;
|
|
32
37
|
/**
|
|
33
|
-
* Create ImageRaw from a URL
|
|
38
|
+
* Create ImageRaw from a URL
|
|
39
|
+
* Works in both main thread and Web Worker
|
|
40
|
+
* Uses fetch + createImageBitmap for best performance
|
|
34
41
|
*/
|
|
35
42
|
static open(url: string): Promise<ImageRaw>;
|
|
36
43
|
/**
|
|
37
44
|
* Create ImageRaw from an ImageBitmap
|
|
45
|
+
* Works in both main thread and Web Worker
|
|
38
46
|
* Note: This method will close the ImageBitmap after conversion to free memory
|
|
39
47
|
* @param bitmap - ImageBitmap to convert
|
|
40
48
|
* @returns Promise<ImageRaw>
|
|
41
49
|
*/
|
|
42
50
|
static fromImageBitmap(bitmap: ImageBitmap): Promise<ImageRaw>;
|
|
51
|
+
/**
|
|
52
|
+
* Create ImageRaw from an OffscreenCanvas
|
|
53
|
+
* Works in both main thread and Web Worker
|
|
54
|
+
* @param canvas - OffscreenCanvas to convert
|
|
55
|
+
* @returns Promise<ImageRaw>
|
|
56
|
+
*/
|
|
57
|
+
static fromOffscreenCanvas(canvas: OffscreenCanvas): Promise<ImageRaw>;
|
|
43
58
|
/**
|
|
44
59
|
* Create ImageRaw from an HTMLImageElement
|
|
60
|
+
* Main thread only
|
|
45
61
|
* @param img - HTMLImageElement to convert (must be loaded/decoded)
|
|
46
62
|
* @returns Promise<ImageRaw>
|
|
47
63
|
*/
|
|
48
64
|
static fromHTMLImageElement(img: HTMLImageElement): Promise<ImageRaw>;
|
|
49
65
|
/**
|
|
50
66
|
* Create ImageRaw from an HTMLCanvasElement
|
|
67
|
+
* Main thread only
|
|
51
68
|
* @param canvas - HTMLCanvasElement to convert
|
|
52
69
|
* @returns Promise<ImageRaw>
|
|
53
70
|
*/
|
|
54
71
|
static fromHTMLCanvasElement(canvas: HTMLCanvasElement): Promise<ImageRaw>;
|
|
55
72
|
/**
|
|
56
73
|
* Create ImageRaw from an HTMLVideoElement (captures current frame)
|
|
74
|
+
* Main thread only
|
|
57
75
|
* @param video - HTMLVideoElement to capture from
|
|
58
76
|
* @returns Promise<ImageRaw>
|
|
59
77
|
*/
|
|
60
78
|
static fromHTMLVideoElement(video: HTMLVideoElement): Promise<ImageRaw>;
|
|
61
79
|
constructor({ data, width, height }: ImageRawData);
|
|
80
|
+
/**
|
|
81
|
+
* Debug method - appends canvas to document body
|
|
82
|
+
* Main thread only, no-op in Worker
|
|
83
|
+
*/
|
|
62
84
|
write(path: string): Promise<void>;
|
|
63
85
|
resize({ width, height }: SizeOption): Promise<this>;
|
|
64
86
|
drawBox(lineImages: LineImage[]): Promise<this>;
|
package/build/ImageRaw.js
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
import { ImageRawBase } from '@areb0s/ocr-common';
|
|
2
2
|
import invariant from 'tiny-invariant';
|
|
3
|
+
// Cache environment checks (evaluated once at module load)
|
|
4
|
+
const IS_WORKER = typeof window === 'undefined' && typeof self !== 'undefined' && typeof document === 'undefined';
|
|
5
|
+
const HAS_OFFSCREEN_CANVAS = typeof OffscreenCanvas !== 'undefined';
|
|
6
|
+
const HAS_DOCUMENT = typeof document !== 'undefined';
|
|
7
|
+
const HAS_IMAGE = typeof Image !== 'undefined';
|
|
8
|
+
const HAS_CREATE_IMAGE_BITMAP = typeof createImageBitmap !== 'undefined';
|
|
9
|
+
// Cache canvas contexts for reuse (WeakMap allows GC when canvas is gone)
|
|
10
|
+
const contextCache = new WeakMap();
|
|
11
|
+
/**
|
|
12
|
+
* Create a canvas that works in both main thread and Web Worker
|
|
13
|
+
* Prefers OffscreenCanvas for better performance
|
|
14
|
+
*/
|
|
15
|
+
function createCanvas(width, height) {
|
|
16
|
+
if (HAS_OFFSCREEN_CANVAS) {
|
|
17
|
+
return new OffscreenCanvas(width, height);
|
|
18
|
+
}
|
|
19
|
+
if (HAS_DOCUMENT) {
|
|
20
|
+
const canvas = document.createElement('canvas');
|
|
21
|
+
canvas.width = width;
|
|
22
|
+
canvas.height = height;
|
|
23
|
+
return canvas;
|
|
24
|
+
}
|
|
25
|
+
throw new Error('No canvas support available. Neither OffscreenCanvas nor document is available.');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get 2D context from any canvas type (cached for performance)
|
|
29
|
+
*/
|
|
30
|
+
function getContext2D(canvas, options) {
|
|
31
|
+
// Check cache first
|
|
32
|
+
const cached = contextCache.get(canvas);
|
|
33
|
+
if (cached)
|
|
34
|
+
return cached;
|
|
35
|
+
// Create new context with performance hints
|
|
36
|
+
const ctx = canvas.getContext('2d', {
|
|
37
|
+
willReadFrequently: true, // Optimize for getImageData() calls
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
if (ctx) {
|
|
41
|
+
contextCache.set(canvas, ctx);
|
|
42
|
+
}
|
|
43
|
+
return ctx;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get ImageData from any canvas type
|
|
47
|
+
*/
|
|
48
|
+
function getImageData(canvas) {
|
|
49
|
+
const ctx = getContext2D(canvas);
|
|
50
|
+
if (!ctx) {
|
|
51
|
+
throw new Error('Failed to get 2D context');
|
|
52
|
+
}
|
|
53
|
+
return ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create ImageBitmap with optimized options for OCR
|
|
57
|
+
* - premultiplyAlpha: 'none' - avoid alpha premultiplication overhead
|
|
58
|
+
* - colorSpaceConversion: 'none' - avoid color space conversion overhead
|
|
59
|
+
*/
|
|
60
|
+
async function createOptimizedImageBitmap(source) {
|
|
61
|
+
if (!HAS_CREATE_IMAGE_BITMAP) {
|
|
62
|
+
throw new Error('createImageBitmap is not supported');
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
// Try with optimization options (may not be supported in all browsers)
|
|
66
|
+
return await createImageBitmap(source, {
|
|
67
|
+
premultiplyAlpha: 'none',
|
|
68
|
+
colorSpaceConversion: 'none',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Fallback without options
|
|
73
|
+
return await createImageBitmap(source);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
3
76
|
export class ImageRaw extends ImageRawBase {
|
|
4
77
|
data;
|
|
5
78
|
#imageData;
|
|
@@ -31,6 +104,12 @@ export class ImageRaw extends ImageRawBase {
|
|
|
31
104
|
static isHTMLVideoElement(input) {
|
|
32
105
|
return typeof HTMLVideoElement !== 'undefined' && input instanceof HTMLVideoElement;
|
|
33
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if the input is an OffscreenCanvas
|
|
109
|
+
*/
|
|
110
|
+
static isOffscreenCanvas(input) {
|
|
111
|
+
return HAS_OFFSCREEN_CANVAS && input instanceof OffscreenCanvas;
|
|
112
|
+
}
|
|
34
113
|
/**
|
|
35
114
|
* Check if the input is ImageRawData
|
|
36
115
|
*/
|
|
@@ -47,7 +126,8 @@ export class ImageRaw extends ImageRawBase {
|
|
|
47
126
|
// ===========================================
|
|
48
127
|
/**
|
|
49
128
|
* Universal factory method that accepts all browser image input types
|
|
50
|
-
*
|
|
129
|
+
* Works in both main thread and Web Worker
|
|
130
|
+
* @param input - URL string, ImageRawData, ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, or HTMLVideoElement
|
|
51
131
|
* @returns Promise<ImageRaw>
|
|
52
132
|
*/
|
|
53
133
|
static async from(input) {
|
|
@@ -55,44 +135,71 @@ export class ImageRaw extends ImageRawBase {
|
|
|
55
135
|
if (typeof input === 'string') {
|
|
56
136
|
return ImageRaw.open(input);
|
|
57
137
|
}
|
|
58
|
-
// ImageBitmap
|
|
138
|
+
// ImageBitmap - Works in both main thread and Worker (most efficient)
|
|
59
139
|
if (ImageRaw.isImageBitmap(input)) {
|
|
60
140
|
return ImageRaw.fromImageBitmap(input);
|
|
61
141
|
}
|
|
62
|
-
//
|
|
142
|
+
// OffscreenCanvas - Works in both main thread and Worker
|
|
143
|
+
if (ImageRaw.isOffscreenCanvas(input)) {
|
|
144
|
+
return ImageRaw.fromOffscreenCanvas(input);
|
|
145
|
+
}
|
|
146
|
+
// HTMLImageElement - Main thread only
|
|
63
147
|
if (ImageRaw.isHTMLImageElement(input)) {
|
|
148
|
+
if (IS_WORKER) {
|
|
149
|
+
throw new Error('HTMLImageElement is not available in Web Worker. Use ImageBitmap instead.');
|
|
150
|
+
}
|
|
64
151
|
return ImageRaw.fromHTMLImageElement(input);
|
|
65
152
|
}
|
|
66
|
-
// HTMLCanvasElement
|
|
153
|
+
// HTMLCanvasElement - Main thread only
|
|
67
154
|
if (ImageRaw.isHTMLCanvasElement(input)) {
|
|
155
|
+
if (IS_WORKER) {
|
|
156
|
+
throw new Error('HTMLCanvasElement is not available in Web Worker. Use OffscreenCanvas instead.');
|
|
157
|
+
}
|
|
68
158
|
return ImageRaw.fromHTMLCanvasElement(input);
|
|
69
159
|
}
|
|
70
|
-
// HTMLVideoElement
|
|
160
|
+
// HTMLVideoElement - Main thread only
|
|
71
161
|
if (ImageRaw.isHTMLVideoElement(input)) {
|
|
162
|
+
if (IS_WORKER) {
|
|
163
|
+
throw new Error('HTMLVideoElement is not available in Web Worker. Use ImageBitmap instead.');
|
|
164
|
+
}
|
|
72
165
|
return ImageRaw.fromHTMLVideoElement(input);
|
|
73
166
|
}
|
|
74
|
-
// ImageRawData (fallback)
|
|
167
|
+
// ImageRawData (fallback) - Works everywhere
|
|
75
168
|
if (ImageRaw.isImageRawData(input)) {
|
|
76
169
|
return new ImageRaw(input);
|
|
77
170
|
}
|
|
78
171
|
throw new Error('Unsupported image input type');
|
|
79
172
|
}
|
|
80
173
|
/**
|
|
81
|
-
* Create ImageRaw from a URL
|
|
174
|
+
* Create ImageRaw from a URL
|
|
175
|
+
* Works in both main thread and Web Worker
|
|
176
|
+
* Uses fetch + createImageBitmap for best performance
|
|
82
177
|
*/
|
|
83
178
|
static async open(url) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
179
|
+
// Prefer fetch + createImageBitmap (works everywhere, better performance)
|
|
180
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
181
|
+
const response = await fetch(url);
|
|
182
|
+
const blob = await response.blob();
|
|
183
|
+
const bitmap = await createOptimizedImageBitmap(blob);
|
|
184
|
+
return ImageRaw.fromImageBitmap(bitmap);
|
|
185
|
+
}
|
|
186
|
+
// Fallback: use Image element (main thread only)
|
|
187
|
+
if (!IS_WORKER && HAS_IMAGE) {
|
|
188
|
+
const image = await imageFromUrl(url);
|
|
189
|
+
const canvas = createCanvas(image.naturalWidth, image.naturalHeight);
|
|
190
|
+
canvasDrawImage(canvas, image, image.naturalWidth, image.naturalHeight);
|
|
191
|
+
const imageData = getImageData(canvas);
|
|
192
|
+
return new ImageRaw({
|
|
193
|
+
data: imageData.data,
|
|
194
|
+
width: imageData.width,
|
|
195
|
+
height: imageData.height,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
throw new Error('Cannot load image from URL: no supported method available');
|
|
93
199
|
}
|
|
94
200
|
/**
|
|
95
201
|
* Create ImageRaw from an ImageBitmap
|
|
202
|
+
* Works in both main thread and Web Worker
|
|
96
203
|
* Note: This method will close the ImageBitmap after conversion to free memory
|
|
97
204
|
* @param bitmap - ImageBitmap to convert
|
|
98
205
|
* @returns Promise<ImageRaw>
|
|
@@ -102,18 +209,14 @@ export class ImageRaw extends ImageRawBase {
|
|
|
102
209
|
if (bitmap.width === 0 || bitmap.height === 0) {
|
|
103
210
|
throw new Error('Invalid ImageBitmap: dimensions are zero (bitmap may be closed or neutered)');
|
|
104
211
|
}
|
|
105
|
-
const canvas =
|
|
106
|
-
|
|
107
|
-
canvas.height = bitmap.height;
|
|
108
|
-
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
|
212
|
+
const canvas = createCanvas(bitmap.width, bitmap.height);
|
|
213
|
+
const ctx = getContext2D(canvas);
|
|
109
214
|
if (!ctx) {
|
|
110
215
|
// Cleanup before throwing
|
|
111
216
|
try {
|
|
112
217
|
bitmap.close();
|
|
113
218
|
}
|
|
114
|
-
catch {
|
|
115
|
-
// Ignore if already closed
|
|
116
|
-
}
|
|
219
|
+
catch { /* ignore */ }
|
|
117
220
|
throw new Error('Failed to create canvas 2D context');
|
|
118
221
|
}
|
|
119
222
|
try {
|
|
@@ -126,28 +229,50 @@ export class ImageRaw extends ImageRawBase {
|
|
|
126
229
|
});
|
|
127
230
|
}
|
|
128
231
|
finally {
|
|
129
|
-
// Always close the bitmap to free memory
|
|
232
|
+
// Always close the bitmap to free GPU/CPU memory
|
|
130
233
|
try {
|
|
131
234
|
bitmap.close();
|
|
132
235
|
}
|
|
133
|
-
catch {
|
|
134
|
-
// Ignore if already closed or neutered
|
|
135
|
-
}
|
|
236
|
+
catch { /* ignore */ }
|
|
136
237
|
}
|
|
137
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Create ImageRaw from an OffscreenCanvas
|
|
241
|
+
* Works in both main thread and Web Worker
|
|
242
|
+
* @param canvas - OffscreenCanvas to convert
|
|
243
|
+
* @returns Promise<ImageRaw>
|
|
244
|
+
*/
|
|
245
|
+
static async fromOffscreenCanvas(canvas) {
|
|
246
|
+
const imageData = getImageData(canvas);
|
|
247
|
+
return new ImageRaw({
|
|
248
|
+
data: imageData.data,
|
|
249
|
+
width: imageData.width,
|
|
250
|
+
height: imageData.height,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
138
253
|
/**
|
|
139
254
|
* Create ImageRaw from an HTMLImageElement
|
|
255
|
+
* Main thread only
|
|
140
256
|
* @param img - HTMLImageElement to convert (must be loaded/decoded)
|
|
141
257
|
* @returns Promise<ImageRaw>
|
|
142
258
|
*/
|
|
143
259
|
static async fromHTMLImageElement(img) {
|
|
260
|
+
if (IS_WORKER) {
|
|
261
|
+
throw new Error('HTMLImageElement is not available in Web Worker. Use ImageBitmap instead.');
|
|
262
|
+
}
|
|
144
263
|
// Ensure image is loaded
|
|
145
264
|
if (!img.complete || img.naturalWidth === 0) {
|
|
146
265
|
await img.decode();
|
|
147
266
|
}
|
|
148
|
-
|
|
267
|
+
// Use createImageBitmap if available (more efficient)
|
|
268
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
269
|
+
const bitmap = await createOptimizedImageBitmap(img);
|
|
270
|
+
return ImageRaw.fromImageBitmap(bitmap);
|
|
271
|
+
}
|
|
272
|
+
// Fallback to canvas
|
|
273
|
+
const canvas = createCanvas(img.naturalWidth, img.naturalHeight);
|
|
149
274
|
canvasDrawImage(canvas, img, img.naturalWidth, img.naturalHeight);
|
|
150
|
-
const imageData =
|
|
275
|
+
const imageData = getImageData(canvas);
|
|
151
276
|
return new ImageRaw({
|
|
152
277
|
data: imageData.data,
|
|
153
278
|
width: imageData.width,
|
|
@@ -156,11 +281,15 @@ export class ImageRaw extends ImageRawBase {
|
|
|
156
281
|
}
|
|
157
282
|
/**
|
|
158
283
|
* Create ImageRaw from an HTMLCanvasElement
|
|
284
|
+
* Main thread only
|
|
159
285
|
* @param canvas - HTMLCanvasElement to convert
|
|
160
286
|
* @returns Promise<ImageRaw>
|
|
161
287
|
*/
|
|
162
288
|
static async fromHTMLCanvasElement(canvas) {
|
|
163
|
-
|
|
289
|
+
if (IS_WORKER) {
|
|
290
|
+
throw new Error('HTMLCanvasElement is not available in Web Worker. Use OffscreenCanvas instead.');
|
|
291
|
+
}
|
|
292
|
+
const imageData = getImageData(canvas);
|
|
164
293
|
return new ImageRaw({
|
|
165
294
|
data: imageData.data,
|
|
166
295
|
width: imageData.width,
|
|
@@ -169,17 +298,25 @@ export class ImageRaw extends ImageRawBase {
|
|
|
169
298
|
}
|
|
170
299
|
/**
|
|
171
300
|
* Create ImageRaw from an HTMLVideoElement (captures current frame)
|
|
301
|
+
* Main thread only
|
|
172
302
|
* @param video - HTMLVideoElement to capture from
|
|
173
303
|
* @returns Promise<ImageRaw>
|
|
174
304
|
*/
|
|
175
305
|
static async fromHTMLVideoElement(video) {
|
|
306
|
+
if (IS_WORKER) {
|
|
307
|
+
throw new Error('HTMLVideoElement is not available in Web Worker. Use ImageBitmap instead.');
|
|
308
|
+
}
|
|
176
309
|
if (video.readyState < 2) {
|
|
177
310
|
throw new Error('Video is not ready. Ensure video has loaded metadata and data.');
|
|
178
311
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
312
|
+
// Use createImageBitmap if available (more efficient, direct GPU access)
|
|
313
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
314
|
+
const bitmap = await createOptimizedImageBitmap(video);
|
|
315
|
+
return ImageRaw.fromImageBitmap(bitmap);
|
|
316
|
+
}
|
|
317
|
+
// Fallback to canvas
|
|
318
|
+
const canvas = createCanvas(video.videoWidth, video.videoHeight);
|
|
319
|
+
const ctx = getContext2D(canvas);
|
|
183
320
|
if (!ctx) {
|
|
184
321
|
throw new Error('Failed to create canvas 2D context');
|
|
185
322
|
}
|
|
@@ -195,48 +332,59 @@ export class ImageRaw extends ImageRawBase {
|
|
|
195
332
|
// Constructor & Instance Methods
|
|
196
333
|
// ===========================================
|
|
197
334
|
constructor({ data, width, height }) {
|
|
198
|
-
|
|
335
|
+
// Avoid unnecessary copy if already Uint8ClampedArray
|
|
336
|
+
const newData = data instanceof Uint8ClampedArray
|
|
337
|
+
? new Uint8ClampedArray(data.buffer, data.byteOffset, data.length)
|
|
338
|
+
: new Uint8ClampedArray(data);
|
|
199
339
|
super({
|
|
200
340
|
data: newData,
|
|
201
341
|
width,
|
|
202
342
|
height,
|
|
203
343
|
});
|
|
204
|
-
const canvas =
|
|
205
|
-
const imageData = new ImageData(newData, width, height);
|
|
344
|
+
const canvas = createCanvas(width, height);
|
|
345
|
+
const imageData = new ImageData(new Uint8ClampedArray(newData), width, height);
|
|
206
346
|
canvasPutImageData(canvas, imageData);
|
|
207
347
|
this.#canvas = canvas;
|
|
208
348
|
this.#imageData = imageData;
|
|
209
|
-
this.data = newData;
|
|
349
|
+
this.data = newData;
|
|
210
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Debug method - appends canvas to document body
|
|
353
|
+
* Main thread only, no-op in Worker
|
|
354
|
+
*/
|
|
211
355
|
async write(path) {
|
|
212
|
-
|
|
356
|
+
if (!IS_WORKER && HAS_DOCUMENT && this.#canvas instanceof HTMLCanvasElement) {
|
|
357
|
+
document.body.append(this.#canvas);
|
|
358
|
+
}
|
|
359
|
+
// In Worker environment, this is a no-op
|
|
213
360
|
}
|
|
214
361
|
async resize({ width, height }) {
|
|
215
362
|
invariant(width !== undefined || height !== undefined, 'both width and height are undefined');
|
|
216
363
|
const newWidth = width || Math.round((this.width / this.height) * height);
|
|
217
364
|
const newHeight = height || Math.round((this.height / this.width) * width);
|
|
218
|
-
const newCanvas =
|
|
365
|
+
const newCanvas = createCanvas(newWidth, newHeight);
|
|
219
366
|
canvasDrawImage(newCanvas, this.#canvas, newWidth, newHeight);
|
|
220
|
-
const newImageData =
|
|
367
|
+
const newImageData = getImageData(newCanvas);
|
|
221
368
|
return this.#apply(newImageData);
|
|
222
369
|
}
|
|
223
370
|
async drawBox(lineImages) {
|
|
224
|
-
|
|
371
|
+
const ctx = getContext2D(this.#canvas);
|
|
372
|
+
if (!ctx) {
|
|
373
|
+
throw new Error('Failed to get 2D context');
|
|
374
|
+
}
|
|
375
|
+
ctx.strokeStyle = 'red';
|
|
225
376
|
for (const lineImage of lineImages) {
|
|
226
377
|
const [first, ...rests] = lineImage.box;
|
|
227
|
-
|
|
228
|
-
|
|
378
|
+
ctx.beginPath();
|
|
379
|
+
ctx.moveTo(first[0], first[1]);
|
|
229
380
|
for (const rest of rests) {
|
|
230
|
-
|
|
381
|
+
ctx.lineTo(rest[0], rest[1]);
|
|
231
382
|
}
|
|
232
|
-
|
|
233
|
-
|
|
383
|
+
ctx.closePath();
|
|
384
|
+
ctx.stroke();
|
|
234
385
|
}
|
|
235
386
|
return this;
|
|
236
387
|
}
|
|
237
|
-
get #ctx() {
|
|
238
|
-
return this.#canvas.getContext('2d');
|
|
239
|
-
}
|
|
240
388
|
#apply(imageData) {
|
|
241
389
|
canvasPutImageData(this.#canvas, imageData);
|
|
242
390
|
this.#imageData = imageData;
|
|
@@ -245,16 +393,6 @@ export class ImageRaw extends ImageRawBase {
|
|
|
245
393
|
this.height = imageData.height;
|
|
246
394
|
return this;
|
|
247
395
|
}
|
|
248
|
-
#putImageData() {
|
|
249
|
-
this.#canvas.width = this.width;
|
|
250
|
-
this.#canvas.height = this.height;
|
|
251
|
-
this.#ctx.putImageData(this.#imageData, 0, 0);
|
|
252
|
-
return this;
|
|
253
|
-
}
|
|
254
|
-
#drawImage(image, width, height) {
|
|
255
|
-
canvasDrawImage(this.#canvas, image, width, height);
|
|
256
|
-
return this;
|
|
257
|
-
}
|
|
258
396
|
}
|
|
259
397
|
// ===========================================
|
|
260
398
|
// Helper Functions
|
|
@@ -262,18 +400,21 @@ export class ImageRaw extends ImageRawBase {
|
|
|
262
400
|
function canvasDrawImage(canvas, image, width, height) {
|
|
263
401
|
canvas.width = width || image.width;
|
|
264
402
|
canvas.height = height || image.height;
|
|
265
|
-
const ctx = canvas
|
|
403
|
+
const ctx = getContext2D(canvas);
|
|
404
|
+
if (!ctx) {
|
|
405
|
+
throw new Error('Failed to get 2D context');
|
|
406
|
+
}
|
|
266
407
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
267
408
|
}
|
|
268
409
|
function canvasPutImageData(canvas, imageData, width, height) {
|
|
269
|
-
const ctx = canvas.getContext('2d');
|
|
270
410
|
canvas.width = width || imageData.width;
|
|
271
411
|
canvas.height = height || imageData.height;
|
|
412
|
+
const ctx = getContext2D(canvas);
|
|
413
|
+
if (!ctx) {
|
|
414
|
+
throw new Error('Failed to get 2D context');
|
|
415
|
+
}
|
|
272
416
|
ctx.putImageData(imageData, 0, 0);
|
|
273
417
|
}
|
|
274
|
-
function canvasGetImageData(canvas) {
|
|
275
|
-
return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
|
|
276
|
-
}
|
|
277
418
|
async function imageFromUrl(url) {
|
|
278
419
|
const image = new Image();
|
|
279
420
|
image.src = url;
|
package/build/ImageRaw.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageRaw.js","sourceRoot":"","sources":["../src/ImageRaw.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ImageRaw.js","sourceRoot":"","sources":["../src/ImageRaw.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@areb0s/ocr-browser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Fork of @gutenye/ocr-browser with ImageBitmap support. High accurate OCR library for Browser based on PaddleOCR and ONNX runtime. Accepts ImageBitmap, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement as input.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ocr",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"prepublishOnly": "npm run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@areb0s/ocr-common": "1.0.
|
|
37
|
+
"@areb0s/ocr-common": "1.0.1",
|
|
38
38
|
"@gutenye/ocr-models": "^1.2.2",
|
|
39
|
-
"onnxruntime-web": "^1.
|
|
39
|
+
"onnxruntime-web": "^1.23.2"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/ImageRaw.ts
CHANGED
|
@@ -2,10 +2,98 @@ import { ImageRawBase } from '@areb0s/ocr-common'
|
|
|
2
2
|
import type { ImageRawData, LineImage, SizeOption, BrowserImageInput } from '@areb0s/ocr-common'
|
|
3
3
|
import invariant from 'tiny-invariant'
|
|
4
4
|
|
|
5
|
+
// ===========================================
|
|
6
|
+
// Environment Detection & Canvas Factory
|
|
7
|
+
// (Cached for performance)
|
|
8
|
+
// ===========================================
|
|
9
|
+
|
|
10
|
+
type AnyCanvas = HTMLCanvasElement | OffscreenCanvas
|
|
11
|
+
type AnyCanvasContext = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D
|
|
12
|
+
|
|
13
|
+
// Cache environment checks (evaluated once at module load)
|
|
14
|
+
const IS_WORKER = typeof window === 'undefined' && typeof self !== 'undefined' && typeof document === 'undefined'
|
|
15
|
+
const HAS_OFFSCREEN_CANVAS = typeof OffscreenCanvas !== 'undefined'
|
|
16
|
+
const HAS_DOCUMENT = typeof document !== 'undefined'
|
|
17
|
+
const HAS_IMAGE = typeof Image !== 'undefined'
|
|
18
|
+
const HAS_CREATE_IMAGE_BITMAP = typeof createImageBitmap !== 'undefined'
|
|
19
|
+
|
|
20
|
+
// Cache canvas contexts for reuse (WeakMap allows GC when canvas is gone)
|
|
21
|
+
const contextCache = new WeakMap<AnyCanvas, AnyCanvasContext>()
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a canvas that works in both main thread and Web Worker
|
|
25
|
+
* Prefers OffscreenCanvas for better performance
|
|
26
|
+
*/
|
|
27
|
+
function createCanvas(width: number, height: number): AnyCanvas {
|
|
28
|
+
if (HAS_OFFSCREEN_CANVAS) {
|
|
29
|
+
return new OffscreenCanvas(width, height)
|
|
30
|
+
}
|
|
31
|
+
if (HAS_DOCUMENT) {
|
|
32
|
+
const canvas = document.createElement('canvas')
|
|
33
|
+
canvas.width = width
|
|
34
|
+
canvas.height = height
|
|
35
|
+
return canvas
|
|
36
|
+
}
|
|
37
|
+
throw new Error('No canvas support available. Neither OffscreenCanvas nor document is available.')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get 2D context from any canvas type (cached for performance)
|
|
42
|
+
*/
|
|
43
|
+
function getContext2D(canvas: AnyCanvas, options?: CanvasRenderingContext2DSettings): AnyCanvasContext | null {
|
|
44
|
+
// Check cache first
|
|
45
|
+
const cached = contextCache.get(canvas)
|
|
46
|
+
if (cached) return cached
|
|
47
|
+
|
|
48
|
+
// Create new context with performance hints
|
|
49
|
+
const ctx = canvas.getContext('2d', {
|
|
50
|
+
willReadFrequently: true, // Optimize for getImageData() calls
|
|
51
|
+
...options
|
|
52
|
+
}) as AnyCanvasContext | null
|
|
53
|
+
|
|
54
|
+
if (ctx) {
|
|
55
|
+
contextCache.set(canvas, ctx)
|
|
56
|
+
}
|
|
57
|
+
return ctx
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get ImageData from any canvas type
|
|
62
|
+
*/
|
|
63
|
+
function getImageData(canvas: AnyCanvas): ImageData {
|
|
64
|
+
const ctx = getContext2D(canvas)
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new Error('Failed to get 2D context')
|
|
67
|
+
}
|
|
68
|
+
return ctx.getImageData(0, 0, canvas.width, canvas.height)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Create ImageBitmap with optimized options for OCR
|
|
73
|
+
* - premultiplyAlpha: 'none' - avoid alpha premultiplication overhead
|
|
74
|
+
* - colorSpaceConversion: 'none' - avoid color space conversion overhead
|
|
75
|
+
*/
|
|
76
|
+
async function createOptimizedImageBitmap(source: ImageBitmapSource): Promise<ImageBitmap> {
|
|
77
|
+
if (!HAS_CREATE_IMAGE_BITMAP) {
|
|
78
|
+
throw new Error('createImageBitmap is not supported')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
// Try with optimization options (may not be supported in all browsers)
|
|
83
|
+
return await createImageBitmap(source, {
|
|
84
|
+
premultiplyAlpha: 'none',
|
|
85
|
+
colorSpaceConversion: 'none',
|
|
86
|
+
})
|
|
87
|
+
} catch {
|
|
88
|
+
// Fallback without options
|
|
89
|
+
return await createImageBitmap(source)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
5
93
|
export class ImageRaw extends ImageRawBase {
|
|
6
94
|
data: Uint8ClampedArray
|
|
7
95
|
#imageData: ImageData
|
|
8
|
-
#canvas:
|
|
96
|
+
#canvas: AnyCanvas
|
|
9
97
|
|
|
10
98
|
// ===========================================
|
|
11
99
|
// Type Guards
|
|
@@ -39,6 +127,13 @@ export class ImageRaw extends ImageRawBase {
|
|
|
39
127
|
return typeof HTMLVideoElement !== 'undefined' && input instanceof HTMLVideoElement
|
|
40
128
|
}
|
|
41
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Check if the input is an OffscreenCanvas
|
|
132
|
+
*/
|
|
133
|
+
static isOffscreenCanvas(input: unknown): input is OffscreenCanvas {
|
|
134
|
+
return HAS_OFFSCREEN_CANVAS && input instanceof OffscreenCanvas
|
|
135
|
+
}
|
|
136
|
+
|
|
42
137
|
/**
|
|
43
138
|
* Check if the input is ImageRawData
|
|
44
139
|
*/
|
|
@@ -59,36 +154,51 @@ export class ImageRaw extends ImageRawBase {
|
|
|
59
154
|
|
|
60
155
|
/**
|
|
61
156
|
* Universal factory method that accepts all browser image input types
|
|
62
|
-
*
|
|
157
|
+
* Works in both main thread and Web Worker
|
|
158
|
+
* @param input - URL string, ImageRawData, ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, or HTMLVideoElement
|
|
63
159
|
* @returns Promise<ImageRaw>
|
|
64
160
|
*/
|
|
65
|
-
static async from(input: BrowserImageInput): Promise<ImageRaw> {
|
|
161
|
+
static async from(input: BrowserImageInput | OffscreenCanvas): Promise<ImageRaw> {
|
|
66
162
|
// String (URL or data URL)
|
|
67
163
|
if (typeof input === 'string') {
|
|
68
164
|
return ImageRaw.open(input)
|
|
69
165
|
}
|
|
70
166
|
|
|
71
|
-
// ImageBitmap
|
|
167
|
+
// ImageBitmap - Works in both main thread and Worker (most efficient)
|
|
72
168
|
if (ImageRaw.isImageBitmap(input)) {
|
|
73
169
|
return ImageRaw.fromImageBitmap(input)
|
|
74
170
|
}
|
|
75
171
|
|
|
76
|
-
//
|
|
172
|
+
// OffscreenCanvas - Works in both main thread and Worker
|
|
173
|
+
if (ImageRaw.isOffscreenCanvas(input)) {
|
|
174
|
+
return ImageRaw.fromOffscreenCanvas(input)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// HTMLImageElement - Main thread only
|
|
77
178
|
if (ImageRaw.isHTMLImageElement(input)) {
|
|
179
|
+
if (IS_WORKER) {
|
|
180
|
+
throw new Error('HTMLImageElement is not available in Web Worker. Use ImageBitmap instead.')
|
|
181
|
+
}
|
|
78
182
|
return ImageRaw.fromHTMLImageElement(input)
|
|
79
183
|
}
|
|
80
184
|
|
|
81
|
-
// HTMLCanvasElement
|
|
185
|
+
// HTMLCanvasElement - Main thread only
|
|
82
186
|
if (ImageRaw.isHTMLCanvasElement(input)) {
|
|
187
|
+
if (IS_WORKER) {
|
|
188
|
+
throw new Error('HTMLCanvasElement is not available in Web Worker. Use OffscreenCanvas instead.')
|
|
189
|
+
}
|
|
83
190
|
return ImageRaw.fromHTMLCanvasElement(input)
|
|
84
191
|
}
|
|
85
192
|
|
|
86
|
-
// HTMLVideoElement
|
|
193
|
+
// HTMLVideoElement - Main thread only
|
|
87
194
|
if (ImageRaw.isHTMLVideoElement(input)) {
|
|
195
|
+
if (IS_WORKER) {
|
|
196
|
+
throw new Error('HTMLVideoElement is not available in Web Worker. Use ImageBitmap instead.')
|
|
197
|
+
}
|
|
88
198
|
return ImageRaw.fromHTMLVideoElement(input)
|
|
89
199
|
}
|
|
90
200
|
|
|
91
|
-
// ImageRawData (fallback)
|
|
201
|
+
// ImageRawData (fallback) - Works everywhere
|
|
92
202
|
if (ImageRaw.isImageRawData(input)) {
|
|
93
203
|
return new ImageRaw(input)
|
|
94
204
|
}
|
|
@@ -97,22 +207,38 @@ export class ImageRaw extends ImageRawBase {
|
|
|
97
207
|
}
|
|
98
208
|
|
|
99
209
|
/**
|
|
100
|
-
* Create ImageRaw from a URL
|
|
210
|
+
* Create ImageRaw from a URL
|
|
211
|
+
* Works in both main thread and Web Worker
|
|
212
|
+
* Uses fetch + createImageBitmap for best performance
|
|
101
213
|
*/
|
|
102
214
|
static async open(url: string): Promise<ImageRaw> {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
215
|
+
// Prefer fetch + createImageBitmap (works everywhere, better performance)
|
|
216
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
217
|
+
const response = await fetch(url)
|
|
218
|
+
const blob = await response.blob()
|
|
219
|
+
const bitmap = await createOptimizedImageBitmap(blob)
|
|
220
|
+
return ImageRaw.fromImageBitmap(bitmap)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Fallback: use Image element (main thread only)
|
|
224
|
+
if (!IS_WORKER && HAS_IMAGE) {
|
|
225
|
+
const image = await imageFromUrl(url)
|
|
226
|
+
const canvas = createCanvas(image.naturalWidth, image.naturalHeight)
|
|
227
|
+
canvasDrawImage(canvas, image, image.naturalWidth, image.naturalHeight)
|
|
228
|
+
const imageData = getImageData(canvas)
|
|
229
|
+
return new ImageRaw({
|
|
230
|
+
data: imageData.data,
|
|
231
|
+
width: imageData.width,
|
|
232
|
+
height: imageData.height,
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
throw new Error('Cannot load image from URL: no supported method available')
|
|
112
237
|
}
|
|
113
238
|
|
|
114
239
|
/**
|
|
115
240
|
* Create ImageRaw from an ImageBitmap
|
|
241
|
+
* Works in both main thread and Web Worker
|
|
116
242
|
* Note: This method will close the ImageBitmap after conversion to free memory
|
|
117
243
|
* @param bitmap - ImageBitmap to convert
|
|
118
244
|
* @returns Promise<ImageRaw>
|
|
@@ -123,18 +249,12 @@ export class ImageRaw extends ImageRawBase {
|
|
|
123
249
|
throw new Error('Invalid ImageBitmap: dimensions are zero (bitmap may be closed or neutered)')
|
|
124
250
|
}
|
|
125
251
|
|
|
126
|
-
const canvas =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const ctx = canvas.getContext('2d', { willReadFrequently: true })
|
|
252
|
+
const canvas = createCanvas(bitmap.width, bitmap.height)
|
|
253
|
+
const ctx = getContext2D(canvas)
|
|
254
|
+
|
|
131
255
|
if (!ctx) {
|
|
132
256
|
// Cleanup before throwing
|
|
133
|
-
try {
|
|
134
|
-
bitmap.close()
|
|
135
|
-
} catch {
|
|
136
|
-
// Ignore if already closed
|
|
137
|
-
}
|
|
257
|
+
try { bitmap.close() } catch { /* ignore */ }
|
|
138
258
|
throw new Error('Failed to create canvas 2D context')
|
|
139
259
|
}
|
|
140
260
|
|
|
@@ -148,29 +268,53 @@ export class ImageRaw extends ImageRawBase {
|
|
|
148
268
|
height: imageData.height,
|
|
149
269
|
})
|
|
150
270
|
} finally {
|
|
151
|
-
// Always close the bitmap to free memory
|
|
152
|
-
try {
|
|
153
|
-
bitmap.close()
|
|
154
|
-
} catch {
|
|
155
|
-
// Ignore if already closed or neutered
|
|
156
|
-
}
|
|
271
|
+
// Always close the bitmap to free GPU/CPU memory
|
|
272
|
+
try { bitmap.close() } catch { /* ignore */ }
|
|
157
273
|
}
|
|
158
274
|
}
|
|
159
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Create ImageRaw from an OffscreenCanvas
|
|
278
|
+
* Works in both main thread and Web Worker
|
|
279
|
+
* @param canvas - OffscreenCanvas to convert
|
|
280
|
+
* @returns Promise<ImageRaw>
|
|
281
|
+
*/
|
|
282
|
+
static async fromOffscreenCanvas(canvas: OffscreenCanvas): Promise<ImageRaw> {
|
|
283
|
+
const imageData = getImageData(canvas)
|
|
284
|
+
|
|
285
|
+
return new ImageRaw({
|
|
286
|
+
data: imageData.data,
|
|
287
|
+
width: imageData.width,
|
|
288
|
+
height: imageData.height,
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
|
|
160
292
|
/**
|
|
161
293
|
* Create ImageRaw from an HTMLImageElement
|
|
294
|
+
* Main thread only
|
|
162
295
|
* @param img - HTMLImageElement to convert (must be loaded/decoded)
|
|
163
296
|
* @returns Promise<ImageRaw>
|
|
164
297
|
*/
|
|
165
298
|
static async fromHTMLImageElement(img: HTMLImageElement): Promise<ImageRaw> {
|
|
299
|
+
if (IS_WORKER) {
|
|
300
|
+
throw new Error('HTMLImageElement is not available in Web Worker. Use ImageBitmap instead.')
|
|
301
|
+
}
|
|
302
|
+
|
|
166
303
|
// Ensure image is loaded
|
|
167
304
|
if (!img.complete || img.naturalWidth === 0) {
|
|
168
305
|
await img.decode()
|
|
169
306
|
}
|
|
170
307
|
|
|
171
|
-
|
|
308
|
+
// Use createImageBitmap if available (more efficient)
|
|
309
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
310
|
+
const bitmap = await createOptimizedImageBitmap(img)
|
|
311
|
+
return ImageRaw.fromImageBitmap(bitmap)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Fallback to canvas
|
|
315
|
+
const canvas = createCanvas(img.naturalWidth, img.naturalHeight)
|
|
172
316
|
canvasDrawImage(canvas, img, img.naturalWidth, img.naturalHeight)
|
|
173
|
-
const imageData =
|
|
317
|
+
const imageData = getImageData(canvas)
|
|
174
318
|
|
|
175
319
|
return new ImageRaw({
|
|
176
320
|
data: imageData.data,
|
|
@@ -181,11 +325,16 @@ export class ImageRaw extends ImageRawBase {
|
|
|
181
325
|
|
|
182
326
|
/**
|
|
183
327
|
* Create ImageRaw from an HTMLCanvasElement
|
|
328
|
+
* Main thread only
|
|
184
329
|
* @param canvas - HTMLCanvasElement to convert
|
|
185
330
|
* @returns Promise<ImageRaw>
|
|
186
331
|
*/
|
|
187
332
|
static async fromHTMLCanvasElement(canvas: HTMLCanvasElement): Promise<ImageRaw> {
|
|
188
|
-
|
|
333
|
+
if (IS_WORKER) {
|
|
334
|
+
throw new Error('HTMLCanvasElement is not available in Web Worker. Use OffscreenCanvas instead.')
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const imageData = getImageData(canvas)
|
|
189
338
|
|
|
190
339
|
return new ImageRaw({
|
|
191
340
|
data: imageData.data,
|
|
@@ -196,19 +345,29 @@ export class ImageRaw extends ImageRawBase {
|
|
|
196
345
|
|
|
197
346
|
/**
|
|
198
347
|
* Create ImageRaw from an HTMLVideoElement (captures current frame)
|
|
348
|
+
* Main thread only
|
|
199
349
|
* @param video - HTMLVideoElement to capture from
|
|
200
350
|
* @returns Promise<ImageRaw>
|
|
201
351
|
*/
|
|
202
352
|
static async fromHTMLVideoElement(video: HTMLVideoElement): Promise<ImageRaw> {
|
|
353
|
+
if (IS_WORKER) {
|
|
354
|
+
throw new Error('HTMLVideoElement is not available in Web Worker. Use ImageBitmap instead.')
|
|
355
|
+
}
|
|
356
|
+
|
|
203
357
|
if (video.readyState < 2) {
|
|
204
358
|
throw new Error('Video is not ready. Ensure video has loaded metadata and data.')
|
|
205
359
|
}
|
|
206
360
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
361
|
+
// Use createImageBitmap if available (more efficient, direct GPU access)
|
|
362
|
+
if (HAS_CREATE_IMAGE_BITMAP) {
|
|
363
|
+
const bitmap = await createOptimizedImageBitmap(video)
|
|
364
|
+
return ImageRaw.fromImageBitmap(bitmap)
|
|
365
|
+
}
|
|
210
366
|
|
|
211
|
-
|
|
367
|
+
// Fallback to canvas
|
|
368
|
+
const canvas = createCanvas(video.videoWidth, video.videoHeight)
|
|
369
|
+
const ctx = getContext2D(canvas)
|
|
370
|
+
|
|
212
371
|
if (!ctx) {
|
|
213
372
|
throw new Error('Failed to create canvas 2D context')
|
|
214
373
|
}
|
|
@@ -228,53 +387,65 @@ export class ImageRaw extends ImageRawBase {
|
|
|
228
387
|
// ===========================================
|
|
229
388
|
|
|
230
389
|
constructor({ data, width, height }: ImageRawData) {
|
|
231
|
-
|
|
390
|
+
// Avoid unnecessary copy if already Uint8ClampedArray
|
|
391
|
+
const newData = data instanceof Uint8ClampedArray
|
|
392
|
+
? new Uint8ClampedArray(data.buffer, data.byteOffset, data.length)
|
|
393
|
+
: new Uint8ClampedArray(data)
|
|
394
|
+
|
|
232
395
|
super({
|
|
233
396
|
data: newData,
|
|
234
397
|
width,
|
|
235
398
|
height,
|
|
236
399
|
})
|
|
237
|
-
|
|
238
|
-
const
|
|
400
|
+
|
|
401
|
+
const canvas = createCanvas(width, height)
|
|
402
|
+
const imageData = new ImageData(new Uint8ClampedArray(newData), width, height)
|
|
239
403
|
canvasPutImageData(canvas, imageData)
|
|
240
404
|
this.#canvas = canvas
|
|
241
405
|
this.#imageData = imageData
|
|
242
|
-
this.data = newData
|
|
406
|
+
this.data = newData
|
|
243
407
|
}
|
|
244
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Debug method - appends canvas to document body
|
|
411
|
+
* Main thread only, no-op in Worker
|
|
412
|
+
*/
|
|
245
413
|
async write(path: string) {
|
|
246
|
-
|
|
414
|
+
if (!IS_WORKER && HAS_DOCUMENT && this.#canvas instanceof HTMLCanvasElement) {
|
|
415
|
+
document.body.append(this.#canvas)
|
|
416
|
+
}
|
|
417
|
+
// In Worker environment, this is a no-op
|
|
247
418
|
}
|
|
248
419
|
|
|
249
420
|
async resize({ width, height }: SizeOption) {
|
|
250
421
|
invariant(width !== undefined || height !== undefined, 'both width and height are undefined')
|
|
251
422
|
const newWidth = width || Math.round((this.width / this.height) * height!)
|
|
252
423
|
const newHeight = height || Math.round((this.height / this.width) * width!)
|
|
253
|
-
const newCanvas =
|
|
424
|
+
const newCanvas = createCanvas(newWidth, newHeight)
|
|
254
425
|
canvasDrawImage(newCanvas, this.#canvas, newWidth, newHeight)
|
|
255
|
-
const newImageData =
|
|
426
|
+
const newImageData = getImageData(newCanvas)
|
|
256
427
|
return this.#apply(newImageData)
|
|
257
428
|
}
|
|
258
429
|
|
|
259
430
|
async drawBox(lineImages: LineImage[]) {
|
|
260
|
-
|
|
431
|
+
const ctx = getContext2D(this.#canvas)
|
|
432
|
+
if (!ctx) {
|
|
433
|
+
throw new Error('Failed to get 2D context')
|
|
434
|
+
}
|
|
435
|
+
ctx.strokeStyle = 'red'
|
|
261
436
|
for (const lineImage of lineImages) {
|
|
262
437
|
const [first, ...rests] = lineImage.box
|
|
263
|
-
|
|
264
|
-
|
|
438
|
+
ctx.beginPath()
|
|
439
|
+
ctx.moveTo(first[0], first[1])
|
|
265
440
|
for (const rest of rests) {
|
|
266
|
-
|
|
441
|
+
ctx.lineTo(rest[0], rest[1])
|
|
267
442
|
}
|
|
268
|
-
|
|
269
|
-
|
|
443
|
+
ctx.closePath()
|
|
444
|
+
ctx.stroke()
|
|
270
445
|
}
|
|
271
446
|
return this
|
|
272
447
|
}
|
|
273
448
|
|
|
274
|
-
get #ctx() {
|
|
275
|
-
return this.#canvas.getContext('2d')!
|
|
276
|
-
}
|
|
277
|
-
|
|
278
449
|
#apply(imageData: ImageData) {
|
|
279
450
|
canvasPutImageData(this.#canvas, imageData)
|
|
280
451
|
this.#imageData = imageData
|
|
@@ -283,43 +454,33 @@ export class ImageRaw extends ImageRawBase {
|
|
|
283
454
|
this.height = imageData.height
|
|
284
455
|
return this
|
|
285
456
|
}
|
|
286
|
-
|
|
287
|
-
#putImageData() {
|
|
288
|
-
this.#canvas.width = this.width
|
|
289
|
-
this.#canvas.height = this.height
|
|
290
|
-
this.#ctx.putImageData(this.#imageData, 0, 0)
|
|
291
|
-
return this
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
#drawImage(image: CanvasImageSource, width?: number, height?: number) {
|
|
295
|
-
canvasDrawImage(this.#canvas, image, width, height)
|
|
296
|
-
return this
|
|
297
|
-
}
|
|
298
457
|
}
|
|
299
458
|
|
|
300
459
|
// ===========================================
|
|
301
460
|
// Helper Functions
|
|
302
461
|
// ===========================================
|
|
303
462
|
|
|
304
|
-
function canvasDrawImage(canvas:
|
|
463
|
+
function canvasDrawImage(canvas: AnyCanvas, image: CanvasImageSource, width?: number, height?: number) {
|
|
305
464
|
canvas.width = width || (image as any).width
|
|
306
465
|
canvas.height = height || (image as any).height
|
|
307
|
-
const ctx = canvas
|
|
466
|
+
const ctx = getContext2D(canvas)
|
|
467
|
+
if (!ctx) {
|
|
468
|
+
throw new Error('Failed to get 2D context')
|
|
469
|
+
}
|
|
308
470
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
|
|
309
471
|
}
|
|
310
472
|
|
|
311
|
-
function canvasPutImageData(canvas:
|
|
312
|
-
const ctx = canvas.getContext('2d')!
|
|
473
|
+
function canvasPutImageData(canvas: AnyCanvas, imageData: ImageData, width?: number, height?: number) {
|
|
313
474
|
canvas.width = width || imageData.width
|
|
314
475
|
canvas.height = height || imageData.height
|
|
476
|
+
const ctx = getContext2D(canvas)
|
|
477
|
+
if (!ctx) {
|
|
478
|
+
throw new Error('Failed to get 2D context')
|
|
479
|
+
}
|
|
315
480
|
ctx.putImageData(imageData, 0, 0)
|
|
316
481
|
}
|
|
317
482
|
|
|
318
|
-
function
|
|
319
|
-
return canvas.getContext('2d')!.getImageData(0, 0, canvas.width, canvas.height)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
async function imageFromUrl(url: string) {
|
|
483
|
+
async function imageFromUrl(url: string): Promise<HTMLImageElement> {
|
|
323
484
|
const image = new Image()
|
|
324
485
|
image.src = url
|
|
325
486
|
await image.decode()
|