All case studies

Automation · AI tooling

Generating a consistent illustration set at zero API cost

A resumable Python pipeline that produced 68 style-matched illustrations on local hardware — averaging 9 KB each, with the licensing actually checked.

Role
Pipeline design and implementation
Output
68 illustrations, 624 KB total
Cost per image
None — runs on local hardware

Aigaku needed an illustration for every vocabulary example. Commissioning them was too slow, stock art would not match, and a hosted image API meant paying per regeneration during the many rounds it takes to get a style right. I built the pipeline instead.

The problem

A vocabulary app with 68 example words needs 68 illustrations that look like they belong to the same set. Mixed sources look broken, and the images sit inside a mobile APK, so every kilobyte is a download the user pays for.

The real cost of image generation is not the final render — it is the twenty throwaway attempts before the style is right. Per-call pricing makes iteration the expensive part, which is exactly backwards.

Constraints

The boundaries that shaped every decision that followed.

Commercially licensed model, verified

Several popular image models are research-only or non-commercial, and sibling models in the same family often differ. The licence had to be confirmed before the output could ship in a paid app.

Incremental and interruptible

Generating a full set in one sitting is not realistic. The pipeline had to be resumable, skip work already done, and never require a code change to add more.

Small enough to bundle

These assets ride inside the APK alongside audio and stroke data. A conventional PNG set would have been an unacceptable share of the download.

What I built

  1. 01

    Local generation server

    Images are produced against a FLUX.2-klein-4B model served locally. I verified the Apache-2.0 licence directly from the model snapshot and the published model card before committing to it, and documented the check — because other variants in the same family carry non-commercial terms and the difference is easy to miss.

  2. 02

    Style locked in one place

    Consistency comes from a single style constant applied to every prompt, rather than per-image prompt tuning. Changing the look of the whole set is a one-line change and a re-run.

  3. 03

    Handling words you cannot draw

    Abstract vocabulary — morning, night, time — produces mush from a literal prompt, so those route through an explicit subject dictionary. Grammatical particles are skipped outright. And because generated text is reliably wrong, the style constant forbids lettering entirely.

  4. 04

    Resumable by default

    The pipeline skips any image already on disk, with flags to limit a run, target specific keys, or force regeneration. Runs are cheap to stop and restart, which is what makes iterating on style practical.

  5. 05

    Generated index, no manual wiring

    Each run regenerates a Dart index of available images. The app decides between an illustration and a fallback icon by looking that set up, so adding images never touches application code — the pipeline and the app stay decoupled.

  6. 06

    Sized for mobile

    512 px WebP output lands between 4 and 12 KB per illustration. The entire 68-image set is 624 KB — small enough to bundle without a second thought.

Results

68
Illustrations generated, one consistent style
~9 KB
Average size (512 px WebP)
624 KB
Complete set, bundled in-app
$0
Marginal cost per regeneration

Built with

  • Python
  • FLUX.2-klein-4B (Apache-2.0)
  • Local inference server
  • WebP optimisation
  • Dart codegen
  • Idempotent batch design

Working on something similar?

Tell me what you are building and where it is stuck. I will tell you honestly whether I am the right person for it — and roughly what it would take.