Sticker Maker - fotojockovic.com/stickers ========================================== Turns photos, drawings, logos and text into die-cut stickers and sticker sheets, with print-and-cut files for Cricut, Silhouette and print shops. Everything runs in the browser; no image leaves the device. Our own work, written for this tool (MIT licence): - The sticker engine (src-rs/, Rust compiled to WebAssembly: stk.wasm with SIMD, stk-nosimd.wasm without), run in worker.js, with no third-party code or crates in it: * colour cut-out: background modelled as a quadratic colour surface fitted to the image border plus border colour clusters (OKLab), region growing from the border that stops at edges, optional soft shadow removal, thin-streak and speck cleanup, soft edges; magic wand * exact Euclidean distance transforms; signed distance fields of the artwork * offset contour (the border) at an exact width in mm, morphological closing with a minimum inner radius (every inward corner of the cut line is at least that round), island merging / "one piece", hole filling or keeping by area, opening (rounded tips) for stars and hearts * fixed shapes fitted around the artwork (smallest enclosing circle, ellipse, rounded rectangle, square, heart, star, scalloped badge) or cropped inside a photo * marching squares iso-contours, shrink-free (Taubin) smoothing, Ramer-Douglas-Peucker simplification, least-squares cubic Bezier fitting with corner detection * print rasters with bleed and edge-colour extension * true-shape sheet nesting on bitset rasters (erosion by span length, bottom-left placement, several orders, upright preference, 0/90/180/any-angle rotation, keep-out zones), grid layout, and exact clearance measurement on the final outlines * a small neural-network runtime (3x3/1x1 dilated and strided convolutions with WebAssembly SIMD, int8 weights, max pooling, bilinear resizing) that runs IS-Net, and the subject mask post-processing: colour guided filter, hysteresis growth, all sizeable subjects kept, stray bits dropped, enclosed holes filled; tap-to-add / tap-to-remove on the model's map - tools/convert_u2netp.py: converts U^2-Net-family ONNX files (IS-Net) into our compact program + int8 weights. - gl.js: WebGL2 sticker renderer (peel-curl mesh, materials, studio lighting, shadows). - nn-gpu.js: WebGPU compute shaders for the same network (int8 weights expanded on the GPU). - WhatsApp (512 px WebP, 96 px tray icon) and Telegram (512 px PNG) sticker export, in app.js. - export.js: PDF writer (CutContour / Thru-cut separation colour spaces with overprint), SVG, DXF (R12), PNG with DPI (pHYs), ZIP writer, cut-path checks. - text.js, app.js, index.html, the interface texts and translations. - Silhouette registration-mark geometry follows the published defaults of Silhouette Studio (Type 1: 10 mm inset, 20 mm arms, 5 mm square); no code was taken from any implementation. Subject cut-out (downloaded only when a photo is cut out): the site's shared module /static/tools/segment/ (see its CREDITS.txt and README.md), shared with the other fotojockovic.com tools so the model is downloaded once: - BiRefNet (Peng Zheng et al., "Bilateral Reference for High-Resolution Dichotomous Image Segmentation", CAAI AIR 2024), https://github.com/ZhengPeng7/BiRefNet - MIT licence. BiRefNet general (int8 weights, 270 MB) on every device whose WebGPU can run it, BiRefNet lite (int8, 70 MB) as a fallback. - IS-Net "isnet-general-use" (Xuebin Qin et al., ECCV 2022), https://github.com/xuebinqin/DIS - Apache License 2.0; int8 weights (47 MB), from the rembg ONNX export (MIT). Used where WebGPU is missing or a larger model fails. - ONNX Runtime Web 1.30.0 (Microsoft, MIT) runs them, on WebGPU or WebAssembly. - Foreground colour estimation (our JavaScript, after Germer et al. 2020 / PyMatting, MIT) gives the edge pixels the subject's own colour, so no halo of the old background is left inside the white border. Our engine then turns the soft map into the sticker mask (guided filter, every sizeable subject kept, holes filled, stray bits dropped) and keeps it for Tap to add. Earlier versions ran IS-Net in our own WebAssembly/WebGPU runtime (model/isnet.bin, nn-gpu.js, src-rs/src/nn.rs); that code is still in the folder but no longer used by the page. Evaluated but not shipped (on a 55-photo test set): U^2-Netp (Apache-2.0, used in the first version), U^2-Net, MODNet (Apache-2.0), MediaPipe selfie multiclass (Apache-2.0). Published methods the engine builds on (ideas only; no code was copied): - P. F. Felzenszwalb, D. P. Huttenlocher, "Distance Transforms of Sampled Functions", 2012. - K. He, J. Sun, X. Tang, "Guided Image Filtering", 2010/2013. - B. Ottosson, "A perceptual color space for image processing" (OKLab), 2020 - public domain formulas. - P. J. Schneider, "An Algorithm for Automatically Fitting Digitized Curves", Graphics Gems, 1990. - G. Taubin, "A signal processing approach to fair surface design", SIGGRAPH 1995. - E. Welzl, "Smallest enclosing disks (balls and ellipsoids)", 1991. - Adobe PDF Reference (Separation colour spaces, overprint), PNG specification (pHYs), PKWARE APPNOTE (ZIP), AutoCAD DXF R12 reference. Sample images (demo/): - The Metropolitan Museum of Art, Open Access, CC0 1.0. Cut out with this tool's own AI cut-out and resized: parrot.webp - Parrot, Bow Porcelain Factory, ca. 1760, object 192836 owl.webp - Owl, Bow Porcelain Factory, ca. 1760, object 203559 teapot.webp - Teapot, Saint-Cloud factory, ca. 1720-30, object 687439 duck.webp - Duck, Comala, 2nd century BCE - 3rd century CE, object 318963 netsuke.webp - Netsuke, Japan, 18th century, object 59356 wave.jpg - Katsushika Hokusai, Under the Wave off Kanagawa (The Great Wave), ca. 1830-32, object 45434 - The "Hello!" sticker is made in the tool with the Lilita One font. Fonts from Google Fonts (self-hosted), all SIL Open Font License 1.1: Inter Tight, Instrument Serif (interface); for text stickers: Lilita One, Bagel Fat One, Titan One, Pacifico, Lobster, Shrikhand, Bungee, Righteous, Caveat Brush, Abril Fatface, Rubik, Russo One, Comfortaa, Fredoka, Monoton, Noto Sans. Fonts are only loaded when the text editor is used. Shared helpers /static/tools/common/i18n.js, rail.js and sheets.js: our own (fotojockovic.com tools). Facts used for the cutter formats (no code): Cricut Help Center, "How to Print Then Cut in Design Space"; Print Then Cut areas per paper size (Letter 7.44 x 9.94 in, A4 7.2 x 10.62 in, Legal 7.44 x 12.94 in, Tabloid 9.94 x 15.94 in, A3 10.64 x 15.44 in, classic 6.75 x 9.25 in) as published by Cricut users' guides; the 12 mm corner keep-outs for the larger areas are our conservative assumption. Roland/Mimaki/Summa print shop convention: a spot colour named "CutContour" (100% magenta, overprint) marks the cut line. Used only to build and test, never shipped to the browser: Rust and cargo (MIT/Apache-2.0); binaryen (Apache-2.0) for wasm-opt; onnx and onnxruntime (MIT/Apache-2.0) to convert the model and check our runtime against the reference; Python, Pillow, puppeteer-core (Apache-2.0), poppler-utils, mediapipe (Apache-2.0, evaluation only). Test photos for the evaluation (not shipped): Wikimedia Commons files under CC0. No GPL or AGPL code is shipped. Self-hosted web fonts (2026-10-19): Inter Tight, Instrument Serif; text stickers: Lilita One, Bagel Fat One, Titan One, Pacifico, Lobster, Shrikhand, Bungee, Righteous, Caveat Brush, Abril Fatface, Rubik, Russo One, Comfortaa, Fredoka, Monoton, Noto Sans. SIL Open Font License 1.1. The woff2 files are the ones Google Fonts serves (latin, latin-ext, cyrillic, greek subsets where the family has them), stored on our own server under /static/tools/common/fonts// with each family's licence text (OFL.txt) next to them; stylesheet /static/tools/common/fonts/ui.css (text-sticker fonts: stickers-text.css, loaded when the text tool opens). No font request goes to Google.