Skip to content

Commit 2300876

Browse files
committed
Enhance error handling and visualization in WebARKit
- Improved logging for 'getMatrix' and 'lostMarker' events in example HTML files to provide clearer context. - Added corner drawing functionality in the overlay for better visual feedback when corners are detected. - Implemented buffer size validation in WebARKitCVWorkers to catch mismatches early, preventing potential errors in processing. - Enforced strict validation of ImageData buffer lengths in WebARKitCoreCV2, eliminating silent failures and improving debugging.
1 parent 000c0a5 commit 2300876

9 files changed

Lines changed: 96 additions & 64 deletions

File tree

dist/src/Workers/WebARKitCVWorkers.js

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/Workers/WebARKitCVWorkers.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/core/WebARKitCoreCV2.js

Lines changed: 10 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/core/WebARKitCoreCV2.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/webarkitCV.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/example.html

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,41 @@
5555
webarkit.track(track.trackers, cameraView.image).then((t) => {
5656
console.log('tracker: ', t);
5757
window.addEventListener("getMatrix", function (e) {
58-
console.log('infos from getMatix Event: ', e.detail);
58+
console.log('%c infos from getMatrix Event: %o', 'background: orange; color: #000; padding: 2px 4px; border-radius: 3px;', e.detail);
5959
drawOverlay(e.detail.finalImage);
60+
// If corners are provided, draw them on the overlay and
61+
// also call cameraView.drawCorners (internal canvas)
62+
try {
63+
const corners = e.detail.corners;
64+
if (corners && Array.isArray(corners) && corners.length >= 8) {
65+
// draw on overlay so the user sees it
66+
const overlayCtx = overlayCanvas.getContext('2d');
67+
overlayCtx.save();
68+
overlayCtx.strokeStyle = 'lime';
69+
overlayCtx.fillStyle = 'lime';
70+
overlayCtx.lineWidth = 3;
71+
overlayCtx.beginPath();
72+
overlayCtx.moveTo(corners[0], corners[1]);
73+
overlayCtx.lineTo(corners[2], corners[3]);
74+
overlayCtx.lineTo(corners[4], corners[5]);
75+
overlayCtx.lineTo(corners[6], corners[7]);
76+
overlayCtx.closePath();
77+
overlayCtx.stroke();
78+
for (let i = 0; i < 8; i += 2) {
79+
overlayCtx.beginPath();
80+
overlayCtx.arc(corners[i], corners[i+1], 5, 0, Math.PI*2);
81+
overlayCtx.fill();
82+
}
83+
overlayCtx.restore();
84+
85+
// also call cameraView.drawCorners for completeness
86+
if (typeof cameraView.drawCorners === 'function') {
87+
cameraView.drawCorners(corners);
88+
}
89+
}
90+
} catch (err) {
91+
console.warn('Error drawing corners on overlay', err);
92+
}
6093
})
6194
window.addEventListener("lostMarker", function (e) {
6295
console.log('infos from lostMarker Event: ', e.detail);

examples/example_image.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
console.log(t);
3636
var imgElem = document.getElementById("face");
3737
window.addEventListener("getMatrix", function (e) {
38-
console.log(e.detail);
38+
console.log('%c detected and tracked: %o', 'background: orange; color: #000; padding: 2px 4px; border-radius: 3px;', e.detail);
3939
//transformElem(e.detail.matrix, imgElem);
4040
//drawCorners(e.detail.corners);
4141
drawOverlay(e.detail.finalImage);

src/Workers/WebARKitCVWorkers.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ export class WebARKitCVOrbWorker extends AbstractWebARKitCVWorker {
5959

6060
console.log("WebARKitCVOrbWorker process imagedata: ", imagedata);
6161

62+
// Validate ImageData buffer size before posting to worker. This helps
63+
// catch mismatches early (for example when the processing canvas size is
64+
// different from the video dimensions). We log a clear warning so callers
65+
// can fix the producer rather than relying on worker-side fallbacks.
66+
try {
67+
const bufLen = imagedata.data?.buffer?.byteLength ?? 0;
68+
const expected = 4 * imagedata.width * imagedata.height;
69+
if (bufLen !== expected) {
70+
// eslint-disable-next-line no-console
71+
console.warn(
72+
`Posting ImageData to worker: buffer length (${bufLen}) !== 4*width*height (${expected}). This will likely cause an error in the worker.`,
73+
{ bufLen, width: imagedata.width, height: imagedata.height },
74+
);
75+
}
76+
} catch (e) {
77+
// Non-fatal: just log and continue
78+
// eslint-disable-next-line no-console
79+
console.warn("Failed to validate ImageData buffer length:", e);
80+
}
81+
6282
this.worker.postMessage({
6383
type: "process",
6484
// send the actual ImageData buffer and its width/height so the worker

src/core/WebARKitCoreCV2.ts

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -91,40 +91,21 @@ export class WebARKitCoreCV {
9191

9292
const buf = new Uint8ClampedArray(msg.imagedata);
9393
const expectedLen = 4 * width * height;
94+
95+
// Strict validation: don't silently slice/pad mismatched buffers. If the
96+
// buffer length doesn't match the expected 4*width*height, log an error
97+
// and abort processing this frame. This makes debugging easier and avoids
98+
// silently corrupting frames.
9499
if (buf.length !== expectedLen) {
95-
// If the incoming buffer length doesn't match, log a warning and try
96-
// to infer a matching width/height by using the provided vWidth or
97-
// falling back to a best-effort width derived from the buffer length.
98-
// This makes the worker more robust to mismatched sizes from the host.
99100
// eslint-disable-next-line no-console
100-
console.warn(
101-
`ImageData buffer length (${buf.length}) does not match 4*width*height (${expectedLen}). Falling back to derived dimensions.",`,
101+
console.error(
102+
`ImageData buffer length (${buf.length}) does not match 4*width*height (${expectedLen}).`,
102103
{ bufLen: buf.length, width, height },
103104
);
104-
105-
// Derive width from vWidth when available, otherwise try to compute
106-
// a width assuming a common aspect ratio. Keep width integer.
107-
let derivedWidth = width;
108-
let derivedHeight = height;
109-
if (!Number.isFinite(msg.vWidth) || !Number.isFinite(msg.vHeight)) {
110-
// try to infer width from buffer length: pick width = Math.floor(Math.sqrt(bufLen/4))
111-
const pixels = Math.floor(buf.length / 4);
112-
derivedWidth = Math.max(1, Math.floor(Math.sqrt(pixels)));
113-
derivedHeight = Math.max(1, Math.floor(pixels / derivedWidth));
114-
}
115-
116-
// If still mismatched, slice or pad the buffer to expected size for
117-
// the derived dimensions to avoid ImageData construction exceptions.
118-
const derivedExpected = 4 * derivedWidth * derivedHeight;
119-
let finalBuf;
120-
if (buf.length > derivedExpected) finalBuf = buf.slice(0, derivedExpected);
121-
else if (buf.length < derivedExpected) {
122-
finalBuf = new Uint8ClampedArray(derivedExpected);
123-
finalBuf.set(buf);
124-
} else finalBuf = buf;
125-
126-
const imageData = new ImageData(finalBuf, derivedWidth, derivedHeight);
127-
return this.estimateCameraPosition({ id: 0, imageData: imageData });
105+
// Clear memory/state for this id to avoid reusing possibly invalid mats
106+
// on subsequent frames and bail out.
107+
if (this.memoryData[id]) this.clearMemory(this.memoryData[id]);
108+
return;
128109
}
129110

130111
const imageData = new ImageData(buf, width, height);

0 commit comments

Comments
 (0)