← All work

Case study // 04

Zonova Lens

A photography studio site with a camera-to-gallery image pipeline.

Role
Engineer
Year
2026
Category
Web
Status
Live
Visit live
  • Astro
  • Cloudflare Workers
  • Sharp
  • Node.js

// CONTEXT

The problem

A working photography studio was spending hours per shoot on manual export. Raw captures come off the camera as HEIC, while the web needs responsive JPEG and WebP at several widths, plus a contact sheet so the photographer can choose which frames make the gallery. Every one of those steps was being done by hand in a desktop editor.

// CONSTRAINTS

What made it hard

  • Input is HEIC, which browsers do not render and most Node tooling does not decode natively.
  • Galleries run to hundreds of frames per shoot, so per-image manual work does not scale.
  • The site is static on Cloudflare Workers, so the pipeline had to run at build time, not per request.

// DECISIONS

What I chose, and what I didn't

  1. 01

    Build a Node pipeline on Sharp that ingests HEIC and derives every responsive format in one pass, plus a generated contact sheet.

    Why

    One command takes a folder of raw captures to a publishable gallery. The contact sheet means curation happens on a single image instead of by scrubbing a directory.

    Instead of

    An on-demand image CDN, which would have solved resizing but not HEIC ingestion or curation, and would have added a per-request dependency to a site that is otherwise fully static.

  2. 02

    Run the pipeline at build time rather than on request.

    Why

    The gallery changes when a shoot is published, not when a visitor arrives. Precomputing means Workers serves static assets with no image processing in the request path.

    Instead of

    Runtime transformation, which spends CPU on every cold request to produce a result that is identical every time.

// OUTCOME

What came of it

  • A shoot goes from camera to published gallery without a manual export step.
  • Responsive formats and contact sheets generated in a single pass.

// REFLECTION

What I'd do differently

The pipeline is currently invoked manually. The obvious next step is a watched folder or a small upload endpoint so the photographer never touches a terminal.