Files
Art-gallery/Documentation/data-and-images.md
T
Danila KhodjaefandCursor 792a0b1a77 Improve 3D gallery UX, placeholders, and image accuracy.
Add multi-row dynamic halls, eye-level camera, canvas covers for missing works, preserved view when returning from detail, and corrected image overrides for Kauffman and Raphael. Update documentation and add fetched painting assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 11:40:08 +03:00

4.3 KiB
Raw Blame History

Art Gallery — data and images

How catalog content and artwork files enter the system.

Principles

  1. No runtime hot-linking — the UI reads from /images/… (local disk). External URLs are used only during ingest.
  2. No AI-generated art or text — biographies and descriptions come from Wikipedia; influence notes from curated art-history sources.
  3. Local copies — every displayed image should exist under data/images/ after seeding or fetch.

Directory layout

data/images/
├── portraits/           # Artist headshots
│   └── Claude_Monet.jpg
└── paintings/
    ├── Claude_Monet_Water_Lilies.jpg
    └── thumbs/
        └── Claude_Monet_Water_Lilies_thumb.jpg

File names are sanitised {Artist}_{Title}.{ext}. The image service can rediscover files on disk even when DB paths are empty (server/image-service.jssyncPaintingFromDisk).

Seeding pipeline

npm run seed runs scripts/seed-wikipedia.js, which:

  1. Inserts historical eras and art movements (curated date ranges and colours).
  2. For each curated artist:
    • Fetches Wikipedia intro text for bio_short / bio_full.
    • Downloads a Commons portrait into portraits/.
    • Creates artist periods and paintings.
    • Downloads painting images into paintings/.
  3. Writes painting_influences edges from curated scholarship references.

Those influence edges also power 3D hall navigation: predecessors and successors at each artists exit doorway are computed from this table (see GET /api/artists/:id/navigation in API.md).

Artists are grouped by movement and century; the seed list targets at most ~100 artists per century.

On-demand image resolution

When a painting has no local file, GET /api/paintings/:id/image triggers ensurePaintingImages():

  1. Check DB paths → verify file on disk.
  2. Scan disk by {artist}_{title} pattern.
  3. If still missing and wikipedia_title is set, call scripts/image-fetcher.js:
    • Wikidata → Wikimedia Commons → Wikipedia page image
    • Fallbacks: Met Museum, Art Institute of Chicago, Rijksmuseum APIs
  4. Save full + thumbnail, update DB, serve file.

Requests are deduplicated (inflight map) and timeout after 15 seconds. A 2.5 s delay between external requests reduces rate-limit risk.

POST /api/artists/:id/preload-images runs local-only linking — no network. Call this when entering an artists 3D hall so textures use files already on disk.

The 3D scene uses galleryImageUrl(), which never hits the on-demand API (remote latency breaks WebGL texture loading).

Placeholders

When no image is available:

  • /placeholder-portrait.svg — timeline / movement band portraits
  • /placeholder-art.svg — paintings in lists and detail view
  • 3D gallery — draped canvas cover inside the frame (CanvasCover in VirtualGallery.tsx); shown when there is no local file, the fetch failed, or the texture has not loaded yet

These live in client/public/ (and client/dist/ after build).

Adding new artists manually

  1. Insert rows into artists, artist_periods, paintings (or extend the ARTISTS array in the seed script).
  2. Place image files under data/images/ using the naming convention.
  3. Run npm run sync-image-paths if that script is available, or rely on preload / on-demand sync.
  4. Add influence rows to painting_influences with citation fields where possible.

Image fetcher overrides

scripts/image-fetcher.js includes hand-maintained overrides for ambiguous Wikipedia titles and direct URLs (e.g. works whose Commons name does not match the article title, or when museum search returns the wrong work). Extend these maps when automated resolution fails:

Map Use when
PAINTING_WIKI_OVERRIDES DB / seed title should resolve to a different Wikipedia or Wikidata label
DIRECT_IMAGE_OVERRIDES You know the exact Commons URL (bypasses Met / Art Institute false matches)

Examples already in the repo:

  • Self-Portrait Hesitating → Kauffman, Wikimedia Commons (National Trust)
  • Cherubs of the Sistine Madonna → Raphaels putti detail, Wikimedia Commons

After adding an override, delete any wrong cached file under data/images/paintings/ and re-run fetch or call the on-demand image endpoint for that painting.