Skip to content

I10 — A catalogue in the brand colours: every picture measured, corrected and tried again until it is on brand

A season’s campaign asks for warm, cosy autumn pictures; the brand is navy, cream and ochre. A generator asked for golden hour, pumpkins and a knitted blanket paints exactly that — in oranges and browns. The product is right, the picture is off brand.

This workflow measures every picture against the brand colours with Color Palette — no model, no credits, the same answer every time — and, when the picture is off the palette, makes it again with the measured violations as the correction: which brand colour is missing, which colour came instead, how much of the picture is off the palette. Repeat Until Accepted does it for each product of the catalogue, at most three times, in one run.

The workflow in three stages, with the reference run. 1, the catalogue: three products in a Bundle Manifest, one item per photo with the JSON Enumerator, and the brand colours — navy, light navy, cream, ochre. 2, one attempt, the body: a campaign picture by Lifestyle, a cosy autumn scene with the previous correction, 5 credits; on brand? Color Palette against the brand colours, 0 credits; the correction, written by Text Expression from the measured violations, 0 credits; a dashed arrow labelled next attempt goes back to the picture. 3, until on brand, per product, at most 3 attempts: teapot 0.484, 0.714, 0.685, best attempt 2; shoe 0.418, 0.658, 0.648, best attempt 2; vase 0.411, 0.748, accepted at attempt 2.

The exact graphs are the workflow (as a diagram) and its body, one attempt (as a diagram).

Input Who provides it Reference run
The products the brand, as a bundle of photos three museum pieces of a Delft collection — a teapot, a shoe, a vase with birds — each on a grey studio background
The brand colours the brand #1F3A6E navy, #2F55A4 lighter navy, #F2EBDD cream, #C9963B ochre

The brief for the scene is the same for every product: a cosy autumn afternoon, the product on a table by a window at golden hour, with a knitted blanket, pumpkins and a lit candle.

  • A judge that is a measurement. Color Palette reads the picture’s colours and checks them against the brand’s (reference_colors): each brand colour must be present (a colour of the picture within OKLab 0.12 of it), and at most 30 % of the picture may be in colours far from every brand colour (max_off_palette 0.3). Whites, greys and blacks never count against it. The verdict is the check’s status: Extract status, Predicate equals passed.
  • A score anyone can read: 1 − the share of the picture off the palette, with Calculate on the check (round(1 - check.metrics.off_palette_proportion, 3)).
  • A correction written by the measurement. Text Expression writes the check’s summary and violations, then the requirement in full: “The picture is off brand: 2 of 4 reference color(s) found; 58.9% of the image off the palette. Reference color #1F3A6E is not in the image: the nearest is #51341E, … Keep the product exactly as it is. Change the setting, the props and the light so that the picture keeps to the brand colours …: no warm orange, red or brown tones.” It reaches Lifestyle’s instructions input on the next attempt. No model writes it, so it cannot disagree with the verdict.
  • The whole catalogue in one run. The products come as a Bundle Manifest, the JSON Enumerator opens one item per photo, and the step runs once per item: every product has its own attempts and its own report, in parallel.
Phase Steps What they do here
A — the catalogue Products, Assets, Each product, Brand colours Bundle Manifest Input; Extract assets; JSON Enumerator mapping storageRef to the photo and metadata.name to the name
B — one attempt (the body) Campaign picture Lifestyle, 4:5, the autumn brief; instructions ← Previous feedback
Brand colours? Color Palette, 8 colours, reference_colors, max_distance 0.12, max_off_palette 0.3
Status, On brand?, Score Extract status → Predicate equals passed → accepted; Calculate → score
Correction Text Expression from the check and the brand colours → feedback
C — until on brand Until on brand Repeat Until Accepted: the body, max_attempts 3, on_exhausted best; per product

One row per product, one column per attempt. The teapot: attempt 1 on a wooden table among orange pumpkins and a rust blanket at golden hour; attempts 2 and 3 on a white or stone table before a blue evening window, with navy knitwear, blue and cream pumpkins and a navy candle. The shoe: attempt 1 among orange pumpkins on a wooden table; attempt 2 with grey-green pumpkins and a mixed blanket; attempt 3 on a dark navy table with navy knitwear and cream pumpkins. The vase: attempt 1 on a wooden table in warm sunset light; attempt 2 on a navy table before a blue window, with cream pumpkins and a blue candle.

Product Attempt 1 Attempt 2 Attempt 3 Delivered
teapot 0.484 — 2 of 4 brand colours, 51.6 % off 0.714 — 2 of 4, 28.6 % off 0.685 — 4 of 4, 31.5 % off attempt 2, best not accepted
shoe 0.418 — 2 of 4, 58.2 % off 0.658 — 3 of 4, 34.2 % off 0.648 — 3 of 4, 35.2 % off attempt 2, best not accepted
vase 0.411 — 2 of 4, 58.9 % off 0.748 — 4 of 4, 25.2 % off — attempt 2, accepted

40 credits for eight attempts — 5 each, for Lifestyle; the measurement and the correction are free. The worst case, 45 credits (3 products × 3 attempts × 5), was reserved as soon as the bundle was read, and what was not spent went back when the run ended. The reports are the step’s report output, one per product.

What the run shows:

  • The first correction does the work. Every product jumped at its second attempt, from about half the picture off the palette to about a quarter, with the warm oranges replaced by navy blankets, blue candles and cream pumpkins. The products themselves did not change: the correction says keep the product exactly as it is.
  • A threshold is a line. The teapot’s third attempt found all four brand colours and missed only by its share off the palette, 31.5 % against 30 %. on_exhausted: best delivers the best attempt anyway, marked best_unaccepted, for a person to approve or for a looser rule.
  • The third attempt rarely helps once the first correction has been applied: three is enough.

The same measurement, first set to OKLab 0.08 and 20 %, rejected pictures a person would call on brand: in a photograph the brand navy comes out a little brighter on a blanket. Calibrate a measurement on a few pictures of the kind you will generate, and include the lighter and darker shades the brand allows.

  • Your brand. The brand colours are one input; add the shades the brand allows. For flat designs (banners, illustrations) a smaller distance and off-palette share hold; for photographs, start from 0.12 and 30 %.
  • Your scene. The brief is Lifestyle’s custom_prompt in the body; the correction keeps it, adding only what the measurement found.
  • More rules. Put other checks in the same body — the subject’s size with Measure Subject, the exposure with Image Statistics — and accept when all pass (Combine Conditions). Write each check’s violations into the correction.
  • A person for the rest. Route the step’s disposition: publish accepted, send best_unaccepted to review.
Terminal window
node madoo-install-example.mjs i10-brand-catalogue --api <your Madoo API URL> --key <key.json> --run --save catalogue

The installer uploads the three photos, composes the bundle, installs and publishes the body, then the workflow that calls it. Running it generates up to nine pictures: about 40 credits, 45 at most — check with the estimate first (it is deferred until the bundle is read).

The products are public-domain pieces of The Metropolitan Museum of Art (Open Access); the pictures were made by Lifestyle’s default model, for this example.

manifest · workflow · body · reports · the complete graph · the body as a graph