@snap-smart/core
v1.2.2
Published
Snap Smart auto corner detection (OpenCV)
Maintainers
Readme
@snap-smart/core
Snap Smart — browser-side auto corner detection for perspective cropping, plus shared photo-tip UI.
Built for real photos of flat subjects (documents, product faces, box sides). Powers Cropper and 3DboxME (six photos → 3D box). Runs entirely in the client using OpenCV.js; no server upload required for detection.
Features
- Automatic quadrilateral detection — suggests four corner points on a loaded image
- Multi-orientation analysis — tries 0°, 90°, and 180° and picks the best result (helps with shadows and weak horizontal edges)
- Optional aspect ratio — constrain detection when the subject shape is known (e.g. a square box face)
- Confidence + hints — accepts or rejects a result with user-facing guidance when detection fails
- Debug overlays — optional pipeline visualizations for tuning (dev or support)
- Photo tips UI — illustrated do/don’t tips and a branded entry button (
2d/3dtext variants) - Version helpers — log or display
@snap-smart/coreversion in your app
Install
npm install @snap-smart/core @techstark/opencv-js@techstark/opencv-js is a peer dependency — your app must install it and load OpenCV before calling detection.
Local development (monorepo)
If you clone the library next to your app:
"@snap-smart/core": "file:../snap-smart"Quick start — corner detection
1. Load OpenCV
OpenCV must be ready on window.cv before you call suggestCornersFromImage. Typical pattern:
import cvReadyPromise from '@techstark/opencv-js';
cvReadyPromise.then((cv) => {
window.cv = cv;
startYourApp();
});2. Run detection on an image
import { suggestCornersFromImage, formatSnapSmartVersion } from '@snap-smart/core';
console.log(formatSnapSmartVersion()); // "@snap-smart/core 1.2.0"
const img = new Image();
img.onload = async () => {
const result = await suggestCornersFromImage(img, {
aspectRatio: 1.5, // optional — omit for free-form quad
});
if (result.accepted) {
// result.corners — [{ x, y }, …] in image pixel coordinates (TL, TR, BL, BR order)
console.log(result.confidence, result.corners);
} else {
console.warn(result.reason, result.hint);
}
};
img.src = photoUrl;Result shape
| Field | Type | Description |
|--------|------|-------------|
| accepted | boolean | Whether to apply the suggested corners automatically |
| corners | { x, y }[] | Four points in original image space (empty if not accepted) |
| confidence | number | 0–1 score |
| hint | string \| null | Short user message when rejected (show in UI) |
| reason | string \| null | Internal reason code (e.g. disabled, low_confidence) |
| debugVisuals | array \| null | Debug frames when visualization is enabled |
API reference
Corner detection
import {
suggestCornersFromImage,
isAutoCornerDetectEnabled,
AUTO_CORNER_DETECT_ENABLED,
AUTO_CORNER_REFINE_ENABLED,
AUTO_CORNER_DETECT_DEBUG,
AUTO_CORNER_DETECT_DEBUG_VISUALIZE,
} from '@snap-smart/core';suggestCornersFromImage(imgElement, options?)
| Option | Type | Description |
|--------|------|-------------|
| aspectRatio | number \| null | Target width/height ratio; null = any quad |
| debugVisualize | boolean | Per-call debug overlay frames (overrides global flag) |
| debugConsole | boolean | Per-call [cornerDetect] logs in DevTools |
isAutoCornerDetectEnabled()
Returns whether detection is enabled (reads AUTO_CORNER_DETECT_ENABLED).
Debug helpers
import {
createDebugCollector,
isDebugVisualizeEnabled,
} from '@snap-smart/core';Global flags in source (or pass runtime options above):
AUTO_CORNER_DETECT_DEBUG_VISUALIZE— pipeline overlays in consuming appsAUTO_CORNER_DETECT_DEBUG— verbose console logging
Version
import {
SNAP_SMART_VERSION,
getSnapSmartVersion,
formatSnapSmartVersion,
} from '@snap-smart/core';
getSnapSmartVersion(); // { name: '@snap-smart/core', version: '1.2.0' }
formatSnapSmartVersion(); // '@snap-smart/core 1.2.0'Useful in startup logs, about screens, or support tickets.
Photo tips UI
Importing from @snap-smart/core loads photoTips.css via your bundler. You need:
- A CSS-capable bundler (webpack, Vite, etc.) — same as importing
.cssfrom any package - Bootstrap CSS variables on
:root(e.g.--bs-primary) for theming — Cropper and 3DboxME already set these - Iconify (
iconify-icon) in the host page for ✓ / ✗ badges on tip illustrations
Your app owns: page shell, navigation, “Got it” / back buttons, wrapper layout and margins.
The package owns: tip copy, SVG illustrations, entry button markup, and scoped styles.
import {
mountSnapSmartEntryButton,
unmountSnapSmartEntryButton,
mountPhotoTips,
unmountPhotoTips,
getPhotoTipsContent,
normalizePhotoTipsVariant,
} from '@snap-smart/core';
// Entry button — host is an empty div you place in your layout
mountSnapSmartEntryButton(document.getElementById('snap-smart-entry-host'), {
buttonId: 'home-photo-tips-link', // optional
onClick: () => showPhotoTipsPage(),
});
// Tips content only (no nav) — put inside your page body
mountPhotoTips(document.getElementById('photo-tips-content-host'), {
variant: '2d', // '2d' = flat subject / cropper wording
// '3d' = box face / 3DboxME wording
});
// Cleanup when removing the host from the DOM
unmountSnapSmartEntryButton(hostEl);
unmountPhotoTips(hostEl);| Variant | Typical use | Wording |
|---------|-------------|---------|
| '2d' | Single flat subject, perspective crop | “subject”, “surface”, “Shoot squarely” |
| '3d' | One face of a box | “box”, “face”, “Face the box squarely” |
getPhotoTipsContent(variant) returns { lead, tips } if you need the data without mounting DOM.
Bundler notes
The package ships ES modules from src/ (no separate build step). Your bundler should handle:
| Import | Loader |
|--------|--------|
| @snap-smart/core | JS (ESM) |
| ./photoTips.css (pulled in automatically) | style-loader + css-loader (or equivalent) |
| ./snap-smart-animated.svg | asset/resource or file loader |
Example webpack rule (same as Cropper / 3DboxME):
{ test: /\.css$/i, use: ['style-loader', 'css-loader'] },
{ test: /\.svg$/i, type: 'asset/resource' },Develop this package
git clone https://bitbucket.org/Raketten1963/snap-smart.git
cd snap-smart
npm install
npm run devOpens http://localhost:5174 — pick an image, see corners and debug panels. The dev page also includes the Snap Smart entry button and photo tips (2d / 3d switch).
The dev server always passes debugVisualize: true and debugConsole: true to suggestCornersFromImage. Open browser DevTools for logs (not the webpack terminal).
npm run build:dev # smoke-build dev bundle to public/Publish (maintainers)
npm version patch # or minor / major — updates package.json + git tag
git push origin main --tags
npm publishpackage.json includes "publishConfig": { "access": "public" }, so you do not need --access public on each publish.
Verify:
npm view @snap-smart/corePackage page: https://www.npmjs.com/package/@snap-smart/core
Tips for good detection
Snap Smart works best when users follow simple photography rules (plain background, one flat area, fill the frame, four corners visible, square-on camera, even light). Use the built-in photo tips UI to teach that — it materially improves auto-align success.
License
ISC © Henrik Rasmussen
Related projects
- Cropper — perspective cropping for images
- 3DboxME — six box photos → GLB 3D model
Both depend on @snap-smart/core for Snap Smart auto-align and shared photo tips.
