@webarkit/featureset-display
v0.5.0
Published
FeatureSET Display based on ARToolKit, ported thanks to Emscripten
Maintainers
Readme
FeatureSET-Display
Display the contents of NFT marker files (
.iset,.fset,.fset3) — the image preview plus the feature points used for detection and tracking — in a browser, via WebAssembly.
Useful for inspecting markers generated with NFT-Marker-Creator or Nft-Marker-Creator-App : see at a glance whether a marker has enough trackable features, whether they're clustered in a corner, or whether the source image lost contrast during the dataset build.
What you get
For any marker triplet (name.iset + name.fset + name.fset3),
the library:
- Reads the imageSet preview into an HTML5 canvas.
- Overlays the detection feature points as light green circles.
- Overlays the tracking feature points as small red circles.
- Logs the marker dimensions, DPI, and feature-point counts to the browser console.
Install
npm install @webarkit/featureset-displayOr load the UMD bundle directly:
<script src="https://unpkg.com/@webarkit/featureset-display"></script>Quick start (ES module)
<script type="module">
import ARFsetModule from '@webarkit/featureset-display';
const ar = new ARFsetModule.ARFset();
await ar.initialize();
await ar.loadNFTMarker('path/to/marker'); // no extension
ar.display();
</script>The library will create a <canvas id="iSet"> element in the document
body and render the marker preview into it. Use attachCanvas(id)
before initialize() to mount it inside a specific container instead:
const ar = new ARFsetModule.ARFset();
ar.attachCanvas('my-container');
await ar.initialize();
await ar.loadNFTMarker('path/to/marker');
ar.display();Quick start (<script> tag)
<script src="dist/ARFset.umd.js"></script>
<script>
const ar = new ARFset.ARFset();
ar.initialize().then(() => {
ar.loadNFTMarker('path/to/marker');
ar.display();
});
</script>window.ARFset resolves to the same default export as the ESM build.
API
new ARFset(options?)
| Option | Type | Default | Description |
| -------- | ------ | ------- | --------------------------- |
| width | number | 893 | Initial wasm canvas width. |
| height | number | 1117 | Initial wasm canvas height. |
These set the wasm-side initial memory layout. The on-screen canvas is resized at marker-load time to the actual reported marker dimensions, so the defaults don't need to match your marker.
await ar.initialize()
Loads the WebAssembly runtime and prepares the canvas. Must be awaited before anything else.
ar.attachCanvas(id)
Mount the canvas inside an existing DOM element instead of body.
Call before initialize().
await ar.loadNFTMarker(urlPrefix)
Fetches urlPrefix.iset, urlPrefix.fset, and urlPrefix.fset3,
loads them into the wasm filesystem, and dispatches an 'nftMarker'
CustomEvent on document when ready.
await ar.loadNFTMarkerBlob([isetUrl, fset3Url, fsetUrl])
Same as above but for user-uploaded data — pass an array of three
URLs (or data URLs from FileReader.readAsDataURL) in the order
[iset, fset3, fset].
ar.display()
Subscribe to the 'nftMarker' event and render the marker preview
plus feature-point circles whenever a marker loads.
Events dispatched on document
| Event | Detail |
| ----------- | ------------------------------------------------------------------- |
| nftMarker | { numIset, widthNFT, heightNFT, dpi, numFpoints, nftPoints, ... } |
| imageEv | (no detail) — fired after the canvas has been painted |
How it works
flowchart LR
user[User code] -->|loadNFTMarker URL| js[ARFset class JS]
js -->|fetch .iset .fset .fset3| net[network]
net -->|Uint8Array| fs[wasm FS]
js -->|_readNFTMarker arId path| wasm[ARimageFsetDisplay wasm]
wasm -->|reads| fs
wasm -->|nftMarker struct + nftPoints + nftFsetPoints| js
js -->|nftMarker event| display[display handler]
display -->|putImageData + arc| canvas[canvas iSet]The C++ side (emscripten/ARimageFsetDisplay.cpp)
links against WebARKitLib
(a maintained fork of jsartoolkit5 / ARToolKit5) to parse the
.iset / .fset / .fset3 files and extract feature points. The
result is returned through an embind value_object, so JS reads the
data directly from the returned struct — no EM_ASM side-channel.
Build from source
Prerequisites:
Node.js 22+
emsdk with
EMSDKset (runemsdk_env.bat/source emsdk_env.shonce per shell).Python 3 on
PATH(needed byemcc.pyon Windows).Git submodules initialised:
git submodule update --init --recursive
Then:
npm install # devDependencies (vite, vitest, playwright)
npm run build # wasm bundles -> build/
npm run build-es6 # JS bundle -> dist/
npm test # unit tests (Vitest)
npm run test:e2e # browser smoke test (Playwright)To try the example locally:
npm run serve
# open http://localhost:8080/example/example_es6.htmlMigration from 0.3.x
0.4.0 removed the legacy global window.ARfset API and the asm.js
build targets.
Before (0.3.x):
<script src="build/arfset.min.js"></script>
<script>
const ar = new ARfset();
ar.loadNFTMarker('marker', (nft) => { ... });
</script>After (0.4.x), ESM:
<script type="module">
import ARFsetModule from '@webarkit/featureset-display';
const ar = new ARFsetModule.ARFset();
await ar.initialize();
await ar.loadNFTMarker('marker');
ar.display();
</script>After (0.4.x), classic script:
<script src="dist/ARFset.umd.js"></script>
<script>
const ar = new ARFset.ARFset();
ar.initialize().then(() => {
ar.loadNFTMarker('marker');
ar.display();
});
</script>Note the new namespace: window.ARFset exposes { ARFset: class },
so the class is reached as ARFset.ARFset. The class also requires
an initialize() await before loadNFTMarker, where the legacy
global used to dispatch a FeatureSETDisplay-loaded event instead.
License
LGPL-3.0 — see LICENSE.txt.
