METHOD / MEASUREMENTS / LIMITS

How a photo becomes a pattern

A deterministic conversion, a shared Pattern and checks you can reproduce. Here is what BEST does, what we measure, and where the model falls short.

Try the photo converter · Explore actual patterns

Why crossstitchgo

A limited thread palette and visible fabric change an image. Matching each pixel to a raw thread color can lose lightness and detail. BEST evaluates the modeled stitched result, including its contrast, instead of stopping at color matching.

Conversion, editing and export run on your device. No AI model is part of the conversion pipeline. Our macaw showcase source is original generated photography; every resulting stitch and chart is computed by the same product algorithm.

From light to thread

  1. Resize in linear light. Decode sRGB, area-average the light values, then encode sRGB again. The C1 black-and-white checkerboard test produces about 187.5, rather than gamma-space gray 128. Default conversion is 150 stitches wide and 30 requested colors.
  2. Recover local lightness. L* unsharp masking with σ 1.5 gives small edges a chance to survive. Chroma compensation accounts for fabric, with tapered gain for very saturated regions.
  3. Choose a useful palette. Deterministic weighted Lab clustering gives edges, local variation, highlights and shadows more weight. The brightest and darkest candidate threads are reserved.
  4. Match to modeled stitched colors. CIEDE2000 with kL = 0.7 favors lightness. Similar colors are merged while respecting the 70% palette floor; rare colors and stray stitches are cleaned with edge protection.
  5. Evaluate candidates. The design specification describes a nine-grid search: USM {0, 0.2, 0.35} crossed with chroma {1.0, 1.05, 1.1}. The shipped M0 implementation is an adaptive search of up to six candidates, including higher compensation when needed and reduced chroma for near-neutral images. It can stop after four candidates if all gates pass. It ranks gate failures first, then contrast, chroma, far-color error and isolated stitches. This implementation difference is deliberate and recorded; nine-grid search is not claimed as shipped.

Code: src/lib/image.ts, converter.ts, metrics.ts, constants.ts. The selector returns its best candidate even when a new image fails a gate. Passing three regression images does not guarantee every photo passes.

Seven hard lines

“Original” means the photo after linear-light resizing to the stitch grid. Local contrast is mean Sobel gradient magnitude of L* after a σ 0.7 blur. Mean chroma is average √(a*² + b*²). Far-view ΔE00 compares the source and modeled stitched image after a one-cell Gaussian blur. An isolated stitch has no matching neighbor among its eight surrounding cells.

GateMeasureHard line
C2aLocal contrastAt least 95% of the resized original
C2bMean chroma95% to 110% of the original
C2cChroma p95No more than 110% of the original
C2dHighlight L* p99.5At least min(original, 91.6) minus 2
C2eFar-view ΔE00No more than improved() baseline + 0.1
C2fIsolated stitchesNo more than baseline + 1.5 percentage points
C2gColors retainedAt least ceil(0.7 × requested colors)

The C2 baseline is improved(), our conversion without BEST. It still includes palette reduction and cleanup. It is different from the simpler homepage comparison.

Three fixtures. Published results.

Reproduced 2026-11-05, Asia/Shanghai. Each fixture is 150 stitches wide with 30 requested colors. Values below are BEST / improved() baseline. All C2a through C2g checks passed for all three. Fixture photographs are test-only and are not used as site artwork.

FixtureLocal %Chroma %Far ΔE00Isolated %BEST colorsOne run, ms
face97.5 / 90.195.5 / 84.74.304 / 4.4572.63 / 2.0230~3865
pet98.5 / 93.195.6 / 100.63.319 / 3.2783.93 / 2.7730~2237
flower99.1 / 92.695.7 / 108.62.266 / 2.1770.98 / 0.7821~1728

Timings are observations from one local run, not speed promises. BEST does not improve every measure: pet and flower have slightly higher far-color error than baseline, within the +0.1 gate. All three have more isolated stitches, within the +1.5 percentage-point allowance.

The macaw showcase, with full measurements

Homepage labels the product result “crossstitchgo” (the BEST conversion path). Both versions use the same 150 × 150 linear-light grid, 36-color budget and stitched renderer. “Typical basic conversion” is an illustrative algorithm: nearest raw-DMC color by squared Lab distance, keep the most frequent 36 colors, then remap to that palette. It has no USM, fabric compensation, weighted palette, protected extremes or confetti cleanup. It is not a measurement of a competitor.

MeasurecrossstitchgoTypical basic conversion
Local contrast kept99.9%71.7%
Peak highlight L*89.472.5
Mean chroma kept89.9%87.5%
Far ΔE005.0076.776
Isolated stitches4.04%4.92%
Actual colors3636

Limits: this saturated photo misses C2b (mean chroma) and C2e (far-color error against improved()). Its improved baseline far ΔE00 is 4.848, giving a limit of 4.948. The other five gates pass. We publish this case because the visual improvement and the remaining limitations both matter.

Full-precision metrics JSON · Source image · Actual Pattern JSON · Actual exported PDF

A preview of stitches, not a promise of calibration

Blocks, stitched preview and PDF use one Pattern. The Aida renderer includes fabric holes, crossed threads and shadows, using COVER = 0.82, SHADE = 0.86 and a provisional fabric color. Sheen is off by default (SHEEN_DEFAULT_ON=false). These are uncalibrated physical assumptions. Your thread, fabric, lighting and screen will change the appearance.

DMC matching uses the craft-color-codes dataset, CC BY 4.0, with upstream attribution to adrianj/CrossStitchCreator. These digital colors are uncalibrated, not an official guarantee of real-thread color.

Check the paper, too

Color-symbol and black-and-white PDF charts are free. Default cells are 3 mm; adjacent pages repeat 2 rows or columns. Each chart page has a minimap and row/column numbers. Symbol contrast is tested at ≥4.5:1 across the DMC palette. Fonts are embedded; grids and symbols are vector/text rather than a chart screenshot.

C5 parses actual PDFs and compares their cells to the Pattern. C3 checks deterministic output hashes. Physical print tests and Pattern Keeper compatibility are still unverified.

Comparison and portrait presets

The three-palette comparison shares a BEST parameter search on a 48-stitch-wide representative grid, then selects and cleans each palette on the complete output grid. This differs from running three independent full BEST searches. Final metrics count occupied colors, isolated cells with no same-color eight-neighbor, and row-scan thread changes that skip empty cloth. Difficulty is a heuristic, not a predicted completion time.

Portrait mode uses a deterministic YCbCr skin-candidate rule, extra weight and reserved skin colors. Warm objects can also match the rule. On the fixed face regression fixture, candidate-region mean ΔE00 improved from 4.942 to 3.870 (21.69%). This is one reproducible fixture, not evidence across all skin tones or lighting. All physical color estimates remain uncalibrated.

Reproduce the evidence

  1. Run pnpm showcase to build the demonstration from the archived original source. The script writes the optimized source, BEST and naive renders, shared Pattern data, real PDFs and public/showcase/metrics.json.
  2. Run pnpm build, then pnpm test. Converter tests write output/metrics/face.json, pet.json and flower.json, including all seven checks and deterministic hashes. The full suite also parses actual exported PDFs.
  3. Review tests/unit/converter.test.ts, pdf.test.ts and showcase.test.ts. Prompts, source, build logs and the M0_SHOWCASE report are archived under .codex-runs/.

Free and paid, specifically

Free for personal use. Up to 500 × 500 stitches and 80 colors. No sign-up or watermark. Photos stay on your device. This includes 220 history steps and 20 free licensed fonts. Free PDF export here covers an item charged separately by stitchmate and photo2stitch in the dated research; it does not mean every feature of those products is available here.

Prices checked 2026-11-04. Historical research snapshot; plans may change.
ToolFree accessPaid access in the research
crossstitchgo500 × 500, 80 colors, photo conversion, editing and full PDF. No signup or watermark.Personal editing and export stay free. Seller plans are $14.90 per month or $99 per year.
Stitch Fiddle15 charts, 300 × 300, 50 colors, basic editingPremium: $5/mo or $30/yr; photo conversion, unbranded export, larger grids
stitchmate10 patterns, PNG and PDF previews; no signupFull PDF $5.99 each; Personal Pass $99 once; Plus $149 once
xstitchify5 PDF credits on signup; about 20 fontsStandard $9.99/mo or $69.99/yr; Pro $24.99/mo
Pattern KeeperOne-month trial; Android chart reader and trackerAbout $9 once. Different purpose: progress tracking, not photo conversion
makebeadFree multi-craft tools; small export watermarkNo paid tier recorded
FlossCrossFree photo conversion, editor and PDF; up to 300 × 300No paid tier recorded
stitchxcrossFree conversion, editing and watermark-free PDF; local processingNo paid tier seen in the research
photo2stitchOne credit on signupEditable canvas or PDF $5 each; $15/mo for 20 uses
crossstitchmaker.netFree conversion, editing, PDF/PNG; 300 × 300, 40 colorsNo paid tier recorded

FlossCross and stitchxcross also offer free tools. We compare specific limits and exports, not overall quality. Pattern Keeper is a chart tracker; our web tracker includes a practice chart.

The Seller plan is $14.9/mo or $99/yr for selling workflows. Try buyer links, version approval and text branding on the local server. The mock checkout charges nothing.

What remains unverified

Try your own photo