← All case files

Case file 004AR textbooks

The problem

“Our books are printed once. We want every page to keep teaching after it’s printed.”

Solved

For
A school textbook series
Built
AR textbook platform: web app, admin panel, scan + 3D pipeline
Stack
Next.js · Express · Postgres + pgvector · S3 · AI image-to-3D
Result
Number to confirm
After: one scan, and the lion on page 12 steps off the page3D pixel film · made by me

01 · The pain

Ink can’t be updated.

  • A new quiz means a new print run.
  • A mistake on page 12 stays on page 12 for years.
  • The teacher’s answers end up in the students’ bags.

02 · The fix

The code stays printed. What it opens keeps changing.

Play the admin: switch content on and off for page 12 and watch what a scan opens. The printed code never changes, and nothing gets reprinted.

English Reader · page 12

L is for Lion

Printed once

Admin · page 12

0 changes published · reprints needed: 0

What a scan opens

L is for Lion

Quiz

Which word starts with L?

3D model

Lion · spin it, or view it in your room

No code? Point the camera at the picture.

Match: Lion page. Opening it.

  1. L · Lion0.12
  2. T · Tree0.41
  3. H · Horse0.47
  4. W · Wolf0.49
  5. C · Cow0.55

03 · How it works

Three pieces, and a phone that couldn’t remember 500 pictures.

  1. One code per page, not per file

    Each printed QR is a normal web link that stands for a page: series, book, class, page number. Any phone camera can open it, no app needed.

  2. An admin panel decides what’s behind it

    Quizzes, colouring sheets, media and 3D models are added, edited or retired per page, in bulk. Teacher guides sit behind a PIN, so students never need accounts.

  3. A 3D model for every letter

    Models for the English Reader, A for Ant to Z for Zip, were generated from photos by an image-to-3D AI and stored with the page they belong to.

The hard part

Recognising a page without a code.

The usual way is to load every picture’s tracking data onto the phone. The library’s own issue tracker shows six pictures already reaching 32 MB and crashing mid-range phones. The series is planned at around 500.

So the phone just sends a photo. The server turns it into a vector, finds the closest page picture in Postgres, and only answers if it’s close enough. A blurry photo gets “try again”, not a wrong lion.

6 pictures → 32 MB on the phone

1 photo → sent to the server, matched there

Figures from the image-tracking library’s issue tracker (mind-ar-js #22).

04 · What changed

Every page can change without a single reprint.

Pages with a live code
—

Metric to confirm · across the series

Scans
—

Metric to confirm · students and teachers

Schools using it
—

Metric to confirm · licensed schools