Geometry is locked. Material is not.
5 Krea 2 image-to-image recipes · every strength and seed recorded · each re-run against a source it was not derived from, and the tier is that result
2 hold · 1 conditional · 1 partial · 1 narrow · 2 refusals with the evidence
Run it as a one-line script, or drop it in as an agent skill for Claude Code and Codex.
Real output at the strength and seed printed under each frame.
See every pair edge to edge →
Every strength value is the one that produced the paired image, not a suggested starting point. The working band is 0.50–0.60 and it is narrower than it looks.
The reason this repo exists in this shape: a recipe that only works on the pair it was derived from is a screenshot of one result, not a recipe. So each of the five was run again against an unrelated source, and the tier column below is that result rather than an estimate.
| Recipe | Tier | Changes | Strength | Holds up on |
|---|---|---|---|---|
medium-gouache |
holds | photograph → gouache, contours in place | 0.60 | anything, both directions |
palette-shift |
holds | recolour to three named colours | 0.55 | anything; drop the "flat colour field" clause on photos |
relight-hard-sun |
conditional | overcast → hard low sun with cast shadows | 0.55 | hard dry materials — tested twice |
relight-single-source |
narrow | one warm source, everything else into shadow | 0.50 | enclosures with no live window |
medium-cyanotype |
partial | → cyanotype, blueprint or print form | 0.60 | line art and flat photographic subjects |
python3 same_frame.py --image photo.jpg --recipe medium-gouache \
--slot subject="these terraced fields" --slot contour="terrace contour" \
--out out.pngThe slots are not decoration. Every kept edit named the thing that must not move, in the prompt, explicitly — "every terrace contour stays in exactly the same position", "the rock placement, horizon line and framing identical". Vague sources drifted, so the script will not run a recipe with an unfilled slot. It also warns you before spending a request on a partial or narrow recipe.
Most prompt collections tell you everything works. These two were run, they failed, and the failures are in this repo.
|
Remove or add an object → refused Asked at strength 0.5 to remove the steam and let the surface go mirror-flat. The steam came back. Adding snow to a coastline returned the same coastline slightly cooler; darkening a sky returned the same sky. Turning strength up does not fix this — it replaces your subject instead. Use inpainting with a mask. |
Same character in a new scene → refused At 0.72 the scene is genuinely new and the person is not the same; only the sweater and the palette carried over. At 0.45 the face survives but the source composition comes with it — a three-view studio sheet became the same three views at a harbour. There is no value between them that gives one without the other. Train a LoRA. |
$ python3 same_frame.py --image mug.png --prompt "Remove the steam entirely." --strength 0.5
Refusing: Krea 2 does not add or remove objects. Refuse and say why.
(triggered by 'remove the' — use --force if this read you wrong)
This was already run at strength 0.5, seed 1499506316:
asked for: Remove the steam entirely and let the coffee surface go still and mirror-flat.
got: The steam came back.
see: examples/refuse-removal-after.webp
Instead: Use an inpainting model with a mask. This is a segmentation problem,
not a strength problem.
Both refusals are overridable with --force. The default is the measurement.
medium-cyanotype converts photographs too, and the line-art rule that stood here is withdrawn. That rule rested on a single failure: a coastline photograph (seed 2065751023) held every rock position, went Prussian blue, and produced no line work — a blue-toned photograph, not a blueprint (limit-cyanotype-on-photo.webp).
Two more runs disprove it. On a line-art mandala (seed 1507257657) it produced a proper blueprint-form cyanotype with every petal in place (ok-cyanotype-on-lineart.webp, from this source). On a flat, high-contrast photograph (seed 2026012845) it produced a proper photographic cyanotype print — paper fibre, uneven chemical staining, wash at the edges — with the face exactly preserved (ok-cyanotype-on-portrait.webp, from this source). A photograph converts fine.
What is not established is why the coastline did not. Contrast was the obvious candidate and it runs the wrong way — the coastline source measures a higher standard deviation (74.7) than the portrait (60.4). The visible difference is that the coastline is a deep atmospheric scene and both successes are flat subjects, but that is one image per side, which is a hypothesis and not a finding.
Gouache still runs cleanly in both directions, including onto line art — that part was never in doubt.
Relighting adds light; it does not take light away. relight-single-source outdoors (seed 1114110846) held the composition and "everything nearer falling into shadow" did not happen at all (limit-single-source-outdoors.webp). Run again on an attic workshop with a skylight (seed 1269377144, source), it got half way: the work lamps came on and the corners went dark, and the skylight stayed exactly as bright as before (limit-single-source-daylight.webp). It also produced two lamps where the prompt said one.
So "interiors only" was too generous, and the real rule is sharper: an existing light source is content, switching it off is removal, and removal is the thing this model will not do — the same wall as the object-removal refusal, one level down. Use it on corridors, tunnels and windowless rooms. A room with a live window keeps its window.
And the material caveat is now a tested precondition, not a guess. relight-hard-sun was marked partial off a single failure. Run on a board-formed concrete stairwell (seed 561284942, source) it held completely — same treads, same handrail, same skylight, a hard low sun with a clean diagonal shadow down the right wall, and concrete that stayed concrete (ok-relight-on-concrete.webp). The wet-terrace drift was about the material, not the recipe.
As an agent skill
npx skills add sjh9714/same-frameInstalls for Claude Code, Codex, Cursor, Gemini CLI and a dozen other agents in one go. Or clone it into the skills directory yourself:
git clone https://github.com/sjh9714/same-frame ~/.claude/skills/same-frame # or ~/.codex/skills/Standalone — no dependencies beyond the standard library:
git clone https://github.com/sjh9714/same-frame && cd same-frame
printf 'FAL_KEY=%s\n' 'YOUR_KEY' > .env && chmod 600 .env # do not paste keys into a chat
python3 same_frame.py --listGet a key at fal.ai. About $0.008 per megapixel — roughly eight tenths of a cent for a 1024×1024 edit. .env is gitignored.
--list and --dry-run need no key and spend nothing. The first prints every recipe with its tier, its precondition and its known failure mode; the second prints the assembled prompt.
The script is a convenience. The recipe is the prompt and the strength, and both are plain text in recipes.json — so any Krea 2 image-to-image workflow can run them, local ComfyUI included:
python3 same_frame.py --recipe medium-gouache --slot subject="these terraced fields" \
--slot contour="terrace contour" --dry-run
# prints the exact prompt; set denoise/strength to the recipe's value and run it locallyTwo things to know before you carry a number over. strength here is the fal.ai image-to-image parameter; in a ComfyUI graph the equivalent is the KSampler denoise value, and while both are nominally "how much of the source survives", I have not measured that they are the same scale. And the whole band was measured on Krea 2 Turbo. Treat 0.50–0.60 as the place to start looking for your own band, not as a value to copy.
The parts that do transfer without qualification are the prompt phrasing findings — name what must not move, say the change is the only change, and check the source can make the marks you are asking for. Those are about the model, not the endpoint.
The endpoint is deterministic: two runs at the same seed, strength, prompt and input bytes came back differing on 0 of 1,048,576 pixels.
So if a re-run looks different, the input changed. This bites in one specific way — feeding a lossy WebP copy of the PNG an edit was originally made from moved the result by 17.0/255 mean per-pixel. Composition, palette and medium all returned; brush texture did not. Keep the original file. For image-to-image, the seed alone does not reproduce a generation; the seed and the exact input bytes do.
The band is a Krea 2 Turbo measurement on roughly square images. Whether 0.55 means the same thing on Krea 2 non-turbo, on another model, or at 16:9 is untested — re-measure before carrying the number over.
Each recipe was generalisation-tested against exactly one unrelated source. That is enough to separate "works" from "only works on what it came from"; it is not enough to map where a partial recipe stops.
Extracted from awesome-krea-2 — 114 generations, 85 kept, 29 cut, every seed recorded. The two refusals are two of the cuts.
MIT for the code and the prompts. The example images are Krea 2 Turbo output, produced under the Krea 2 Community License, presented as model output rather than as photographs or artwork. The safety checker was enabled on every request.






