# THE COMIC MACHINE — Guide for Claude
### How to make any photo look PRINTED as a comic (by Peter + Claude, 2026)

Hi Claude! This is the companion tool to **THE PAINT MACHINE** (`paint_anything.py`).
Read that guide too if it's in the folder — same rules, same Peter.

**The difference, and Peter cares about it:** the paint machine *paints* a picture with
brush strokes; marker mode there is a *painted* comic. This tool doesn't paint at all.
It pretends the picture went through a **comic printing press**: flat inked colours,
crisp ink outlines, Ben-Day halftone dots for shading, newsprint paper, and (retro
style) printing plates that don't line up perfectly. No strokes anywhere.

---

## STEP 0 — What you need

1. An image (photo, drawing, cartoon — anything)
2. `comicify.py` (the working code, don't rewrite it)
3. Python with **numpy, opencv-python, Pillow**

## STEP 1 — Set the config

Open `comicify.py`, top block:

```python
PHOTO  = "path/to/photo.jpg"
OUT    = "path/to/comic.png"
STYLE  = "clean"      # clean | retro | poster | manga
```

## STEP 2 — Run it

```bash
python3 comicify.py
```

It prints the style, colour count, ink pixels and halftone dot pixels. Peter likes the
numbers — always report them, honestly counted.

## STEP 3 — LOOK at your own output before showing him

Same rule as the paint machine: `view` the PNG yourself first. Check for: ink lines
that vanished, speckle noise in flat areas, dots printed over solid black, the subject
lost in a busy background. Fix, re-run, then present. Peter notices everything.

---

## THE STYLES

| Style    | Look | Colours | Dots | Paper |
|----------|------|---------|------|-------|
| `clean`  | modern comic book, sharp and bright | 10 | light | near-white |
| `retro`  | 1960s newsprint, plates misaligned | 7 | heavy | aged cream |
| `poster` | screenprint / stall sign, big flat shapes | 5 | none | warm white |
| `press`  | **real CMYK printing**: four plates, rosette dots, off-register | 8 | rosette | cream |
| `manga`  | black & white with screentone | 4 greys | full | white |

**`press` is the most authentic one** — see the CMYK section below. Use it when Peter says
"like an old print", "misaligned colours", "you can see the dots".

**Which to pick:** `clean` for characters and mascots; `retro` when he wants it to feel
old and printed; `poster` when the result must read from far away (signs, stickers,
T-shirts — the fewer colours also make it printable/cuttable); `manga` for drama.

## THE DIALS (he'll ask in words — map them yourself, don't ask for numbers)

- **"fewer colours" / "simpler"** → `COLORS = 5` (or 3 for extreme)
- **"more colours" / "richer"** → `COLORS = 14`
- **"thicker lines" / "bolder"** → `INK = 1.5` (thin = 0.7)
- **"too busy" / "too many lines"** → `DETAIL = 0.6`
- **"more detail in the lines"** → `DETAIL = 1.4`
- **"bigger dots" / "more visible dots"** → `DOT = 10`; **"no dots"** → `HALFTONE = "off"`
- **"more colourful / punchier"** → `SAT = 1.5`
- **"no frame"** → `PANEL = False`
- **"bigger / print quality"** → `W = 2200` (slower; dots scale automatically)

## THE CMYK PRESS (`STYLE = "press"`, or `CMYK = "on"` on any style)

Real comics are not printed with one screen of grey dots. They are printed **four times**,
once per ink:

| Plate | Ink | Screen angle |
|---|---|---|
| C | cyan | 15 deg |
| M | magenta | 75 deg |
| Y | yellow | 0 deg |
| K | black | 45 deg |

Those angles are the classic ones, chosen so the four dot grids interfere in a flower
pattern instead of an ugly moire - that flower is called a **rosette**, and it is the
single strongest "this was printed" signal there is.

The picture is separated into the four ink densities (with GCR: `K = 1 - max(R,G,B)`, then
C/M/Y from what is left), each density is screened at its own angle, and the plates are
printed one after another as **transparent inks that multiply** onto the paper colour.

**Misregistration** (`MISREG`, default 2 px in press style): each plate is shifted by a
random small offset before printing, because paper stretches and rollers drift. K is
shifted least, since presses register black most carefully. This is what makes coloured
fringes appear next to the black lines - Peter asked for exactly this and it is the detail
that sells the whole illusion.

- **"more misaligned" / "sloppier press"** -> `MISREG = 4`
- **"perfectly printed"** -> `MISREG = 0` (still rosette dots, just clean)
- **"bigger dots" (rosette more visible)** -> `DOT = 9`
- **CMYK on a different style** -> `CMYK = "on"` (works on clean/retro/poster too)

The screens are computed with vectorised numpy (rotate coordinates, take the distance to
each cell centre, dot radius = 0.56 x sqrt(ink density) so dot AREA is proportional to ink,
which is how real halftones work). The whole four-plate press runs in about 2 seconds.

## HOW IT WORKS (if you must rebuild it)

1. **Load** and resize; flatten transparency onto white.
2. **Bilateral filter ×3** — this is the trick: it smooths colour gradients into flat
   areas while keeping edges razor sharp. Blur would destroy the edges; bilateral doesn't.
3. **Flatten colours** with k-means in **Lab** space (not RGB — Lab groups colours the way
   eyes do). Manga instead posterizes grayscale into N levels.
4. **Ink mask**: Canny edges on the smoothed image (thresholds derived from the median
   brightness, so it adapts per photo) + adaptive-threshold interior lines when
   `DETAIL > 0.9`. Then close small gaps and **despeckle** by dropping connected
   components under ~14 px — without that, textures print as noise dust.
5. **Halftone**: dots on a 45° grid (the classic comic screen angle), radius ∝ √darkness,
   tiny random jitter so it isn't mechanical. Areas darker than lum 45 are set to zero
   shade — **solid blacks must stay solid**, dots inside them look like a bug.
6. **Printing**: either the simple grey dot screen (clean/retro/manga), or the full CMYK
   press described above (press style) - four separations, four screen angles, four
   slightly-off-register passes of transparent ink.
7. **Paper**: grain + coarse fibre noise multiplied over the image.
8. **Ink on top, last** — ink is printed ON the paper, never under it. Getting this
   order wrong makes the lines look faded and wrong.
9. **Panel frame** drawn last on a paper-coloured mat.

## THINGS THAT WENT WRONG WHILE BUILDING IT (learn from me)

- Feeding it a PNG whose **transparency checkerboard is baked into the pixels** — it will
  happily print the checkerboard. Check a corner pixel; if the background varies in a
  grey grid, find a cleaner source file. (`kit/build/snippet.png` is the clean Snippet.)
- Adaptive threshold alone = speckle storm on any texture. Despeckling is not optional.
- Dots over solid black looked like dirt until the `lum < 45 → no dots` rule.
- Paper multiplied over the ink turned the outlines muddy grey. Ink goes last.

## PETER'S CONTEXT

Peter is 11, in Berlin, runs a small 3D-print shop at school called **3D** and draws
Fry City characters (Snippet the baby blue dragon is the mascot of Silly Old Restaurant).
`poster` style output makes great stall signage and stickers — few colours read from far
away. Present the actual file, not a description of it.

Have fun. Count the dots honestly. — Claude
