How to write a picture prompt?
Write half of it and let the tool write the other half — then put your own words between two commas. A picture prompt is the line a model reads to make an image, and on a tool that starts from a picture you already have, one part of that line is measured and one part is yours. The measured part arrives in a fixed order with a gap between every pair of clauses. We put a plain two-word phrase into every one of those gaps, on 480 generated lines, four different ways of attaching it: 12,688 insertions. With a comma on both sides it came back as its own piece, at weight 1, 3,172 times out of 3,172. With a space after it, zero. With a period after it, zero. The rest of this page is the map: how many gaps there are, what each one costs you, and which three characters will change how your words are read.
- Pick the shape and the length. Those are the only two choices you make before the line exists. Everything else in it is computed from your file.
- Run the tool and read what it claims. It writes between 1 and 11 clauses depending on the shape and length, in an order that never changes.
- Add your words with a comma on both sides. Any gap will do. Your phrase comes back as one piece at weight 1, and every clause the tool wrote is still there, byte for byte — 1,188 of 1,188.
- Leave weights alone unless you mean them. A colon followed by a number is read as a weight, not as a ratio.
paper texture 16:9is read as the termpaper texture 16at weight 9.
What these numbers are. Forty real files — 39 photographs at 640 × 360 and one code screenshot at 800 × 450 — were decoded on this machine, box-downsampled to 192 × 192 (the grid the live tool measures on), and composed into four output shapes at three lengths: 480 lines. The clause order was then rebuilt from src/compose.js and checked against those lines character for character — 480 out of 480 matched, so every “gap” below is a real position in a real line, not a guess. Each insertion was re-read with this site’s own weight parser. No model was called and no image was generated.
The line is already in a fixed order, and every gap in it is a comma or a space
Before you can choose a place, you need to know how many places there are. The generator builds a list of clauses and joins them: with a comma for Midjourney and Stable Diffusion, with a space for Flux and DALL·E, because those two are written as sentences. Two shapes also carry a fixed piece you cannot move — Stable Diffusion opens with masterpiece, best quality, and Midjourney closes with --ar and the aspect value.
| Shape | Length | Slots | Places to put your words | Joined with | Fixed piece |
|---|---|---|---|---|---|
| Midjourney | short | 5–6 | 6–7 | comma | tail --ar 16:9 |
| Midjourney | medium | 8–9 | 9–10 | comma | tail --ar 16:9 |
| Midjourney | long | 9–11 | 10–12 | comma | tail --ar 16:9 |
| Stable Diffusion | short | 5–6 | 6–7 | comma | prefix masterpiece, best quality, |
| Stable Diffusion | medium | 8–9 | 9–10 | comma | prefix masterpiece, best quality, |
| Stable Diffusion | long | 9–11 | 10–12 | comma | prefix masterpiece, best quality, |
| Flux | short | 3–4 | 4–5 | space | — |
| Flux | medium | 5–6 | 6–7 | space | — |
| Flux | long | 7–8 | 8–9 | space | — |
| DALL·E | short | 1 | 2 | space | — |
| DALL·E | medium | 2 | 3 | space | — |
| DALL·E | long | 3 | 4 | space | — |
The order itself is not negotiable. src/compose.js makes ten pushes into the clause list; two of them depend on a measurement (the subject, and the vertical-light clause) and the other eight follow the length setting, so short, medium and long are the only levers you have — the same three the entry point exposes as model, length and the file’s own pixel size. There is no switch to drop a clause you disagree with, and there is no second pass: nothing in the pipeline reads what you typed and re-measures the image.
Four ways to attach your words, and one that works everywhere
The parser that reads a prompt back splits on commas. It does not split on periods. That single fact decides everything below. We took a neutral two-word phrase with no punctuation in it and inserted it at every place in every line, four ways.
| Shape | Length | Comma behind | Comma both sides | Space | Period |
|---|---|---|---|---|---|
| Midjourney | short | 83.6% | 100% | 0% | 0% |
| Midjourney | medium | 89.0% | 100% | 0% | 0% |
| Midjourney | long | 90.7% | 100% | 0% | 0% |
| Stable Diffusion | short | 100% | 100% | 0% | 0% |
| Stable Diffusion | medium | 100% | 100% | 0% | 0% |
| Stable Diffusion | long | 100% | 100% | 0% | 0% |
| Flux | short | 48.8% | 100% | 0% | 0% |
| Flux | medium | 32.8% | 100% | 0% | 0% |
| Flux | long | 24.7% | 100% | 0% | 0% |
| DALL·E | short | 100% | 100% | 0% | 0% |
| DALL·E | medium | 66.7% | 100% | 0% | 0% |
| DALL·E | long | 50.0% | 100% | 0% | 0% |
The two failures are worth naming, because they are the only two things that go wrong. In Midjourney, every miss is the same place: the last one, immediately before the --ar tail. Put your words there with only a comma behind them and the parser reads the whole tail as one term — paper texture --ar 16 at weight 9 — on 0 of 40 files does your phrase survive. In the two sentence shapes, a bare comma only works at the very front and the very end: in the middle of a sentence the phrase picks up the tail of the previous sentence, because a period is not a separator here. That is why Flux at the long setting reads 24.7% — two usable places out of eight or nine — and DALL·E reads 50.0%, two out of four.
There is a price for the method that always works, and it is worth knowing before you care about it. A comma on both sides leaves an empty slot between the two commas, so the line no longer survives a round trip through the tool that rewrites every weight explicitly: 0 of 3,172 came back byte-identical. The comma-behind method kept that property on 2,132 of 2,132 non-Midjourney lines. Midjourney lines never round-trip anyway — 0 of 40 before you touch them — because of the same --ar tail. If you never run that rewrite, the empty slot costs you nothing: the parser skips it, and your phrase is one clean term at weight 1.
Midjourney 287 → 302 chars, 14 → 15 terms
before widescreen 16:9 composition, well-lit, balanced exposure, dominant palette of
silver, tan, grey, charcoal, moderately saturated colour, …
after widescreen 16:9 composition, paper texture, well-lit, balanced exposure,
dominant palette of silver, tan, grey, charcoal, moderately saturated colour, …
Stable Diffusion 304 → 319 chars, 16 → 17 terms
after masterpiece, best quality, widescreen 16:9 composition, paper texture, well-lit, …
Flux 241 → 256 chars, 6 → 7 terms
after … Evenly lit. Bright and uplifting atmosphere., paper texture
DALL·E 222 → 237 chars, 9 → 10 terms
after … highly detailed with intricate texture. Bright and uplifting atmosphere., paper texture
(same file, long setting, one two-word phrase; weight 1 in all four)
Where you put them decides how much of the measured line comes first
The gaps are not equivalent in another way: each one sits at a different point along the line, so choosing one also chooses how much of the tool’s own wording precedes yours. Below, the share of the line’s characters that fall before the insertion point, at the long setting.
| Shape | Front | Last | All gaps (median) | Why the ends are not 0 and 100 |
|---|---|---|---|---|
| Midjourney | 0% | 96.65% | 52.95% | --ar 16:9 tail always follows your words |
| Stable Diffusion | 8.5% | 100% | 58.95% | masterpiece, best quality, always precedes them |
| Flux | 0% | 100% | 52.30% | — |
| DALL·E | 0% | 100% | 70.45% | only four gaps, and three of them are late |
At the short and medium settings the shape of this is the same: the front is 0% for every shape except Stable Diffusion, where it is 8.5% to 14.4%, and the last gap is 94.15% to 96.65% for Midjourney and 100% for the other three. If you believe ordering matters for how a model attends to a prompt — and the whole reason Stable Diffusion’s shape carries a quality prefix at the front is that someone did — then this table is the argument for putting your words early. If you do not, it costs you nothing to put them last, which is where they read most naturally.
How long your part can be, and what it costs
Length is the one dimension the parser does not care about. A phrase of one word and a phrase of twenty-seven words behave identically: each is one term, at weight 1, on 160 of 160 lines. What changes is how much of the finished line is yours. The median long line before editing is 278 characters.
| Words you write | Characters added | Share of the new line | Came back as one term | Weight |
|---|---|---|---|---|
| 1 | +9 | 3.1% | 160/160 | 1 |
| 2 | +17 | 5.8% | 160/160 | 1 |
| 4 | +26 | 8.6% | 160/160 | 1 |
| 8 | +54 | 16.3% | 160/160 | 1 |
| 17 | +96 | 25.7% | 160/160 | 1 |
| 27 | +153 | 35.5% | 160/160 | 1 |
Writing several things is just as cheap as writing one, as long as you separate them the way the parser separates things. Two extra phrases add exactly 2 terms and three add 3 — the median change in term count was 1, 2 and 3 for one, two and three phrases, with no spread across the 160 lines. Commas are the only structure this parser honours, so commas are the whole budget.
Three characters that change how your words are read
Everything above assumed you typed plain words. Three characters will change the reading, and one of them does it by accident. The pattern the parser uses for an explicit weight is a colon followed by a number at the end of a term, which means an aspect ratio written inside your own words becomes a weight.
| What you write | Weight read back | Your words still one term | Out of range (of 160 lines) |
|---|---|---|---|
paper texture | 1 | 160/160 | 40 (Midjourney baseline) |
paper texture 16:9 | 9 | 0/160 | 200 |
(paper texture) | 1.1 | 160/160 | 40 (Midjourney baseline) |
[paper texture] | 0.9091 | 160/160 | 40 (Midjourney baseline) |
(paper texture:1.4) | 1.4 | 160/160 | 40 (Midjourney baseline) |
Read the second row carefully, because it is the one that bites. Your phrase is gone as a phrase: the parser read the term as paper texture 16 at weight 9, which is more than five times the top of the usable band, and it did that on all four shapes identically. If you want to say what shape you are after, write it as words — wide, roughly sixteen by nine — or leave it to the shape that already carries the value. The other three rows are deliberate and safe: parentheses and brackets are how weighting is written, they are read as 1.1 and 0.9091 per level, and an explicit :1.4 is honoured exactly. Just remember that what the parser reads is not automatically what every model does with it; this site reports the reading, it does not render anything.
How to write an image prompt: the structure, the ratio, and the camera you supply
Three parts of a finished prompt get asked for by name, and two of them are already in the line the tool hands you. The structure is an order of measured fields that never varies except for two switches. The aspect ratio is arithmetic done on your file’s pixel dimensions — nothing in the picture decides it. The camera is not there at all: no lens, no aperture, no film speed in any of the 480 lines, so every camera word in a finished prompt is one you typed. This section is what each of the three actually is, measured on the same forty files, plus eleven clauses inserted into all 480 lines.
The structure: an order set by two switches, with a width that moves underneath it
Across all twelve shape-and-length combinations, the order of the measured fields is not decided per image. It is decided by two conditions: whether the subject clause fires (it fires on 4 of the 40 files, the ones past a monochrome ratio of 0.85) and whether the vertical-light clause fires (28 of 40). Inside each of those groups the order is identical on every file — 12 combinations out of 12. What does move is the width. Only three fields keep the same word count on all forty files (ar, subject, vert); the other nine swell and shrink, the palette clause between 3 and 6 words across 37 different values, and the light-distribution clause between 2 and 8.
| Shape | Length | Line words | Groups (files each) | Widest field |
|---|---|---|---|---|
| Midjourney | short | 21 – 22 – 27 | 2 (36 / 4) | palette, 3–6 words |
| Midjourney | medium | 29 – 34 – 41 | 2 (36 / 4) | light distribution, 2–8 words |
| Midjourney | long | 33 – 39 – 45 | 4 (9 / 27 / 3 / 1) | light distribution, 2–8 words |
| Stable Diffusion | short | 22 – 23 – 28 | 2 (36 / 4) | palette, 3–6 words |
| Stable Diffusion | medium | 30 – 35 – 42 | 2 (36 / 4) | light distribution, 2–8 words |
| Stable Diffusion | long | 34 – 40 – 46 | 4 (9 / 27 / 3 / 1) | light distribution, 2–8 words |
| Flux | short | 14 – 16 – 25 | 2 (36 / 4) | palette, 3–6 words |
| Flux | medium | 25 – 27 – 36 | 2 (36 / 4) | light distribution, 2–8 words |
| Flux | long | 31 – 36 – 47 | 2 (36 / 4) | light distribution, 2–8 words |
| DALL·E | short | 14 – 16 – 22 | 2 (36 / 4) | palette, 3–6 words |
| DALL·E | medium | 25 – 27 – 33 | 2 (36 / 4) | palette, 3–6 words |
| DALL·E | long | 29 – 31 – 36 | 2 (36 / 4) | palette, 3–6 words |
For a sense of scale, here is the other way round: twelve image prompts written by hand the way people write them — subject first, then a few details — read back with the same parser. A median of 11.5 words and 69.5 characters, three pieces each, 41 terms across the twelve. Three of them carried a weight that was not 1, one went outside the usable band (the one ending in 16:9), and 9 of the 12 survived a round trip through the explicit-weight writer unchanged. Against a generated line of 31 to 40 words at the long setting, a hand-written line is between 29% and 37% of it — which is the honest answer to “how much do I need to write”: you are topping up a line, not building one.
The ratio: two integers from your file, and one ratio can come out as two different strings
The aspect value is not read off the picture. aspectParam takes the file’s width and height, divides both by their greatest common divisor, and only if either number is still above 60 scales both down to sixty — which is why the two sizes in this corpus, 640 × 360 on 39 files and 800 × 450 on one, both come out as 16:9. We swept every size from 200 × 200 to 2000 × 2000: 3,243,601 sizes, 2,064 distinct strings. The two largest buckets are 59:60 and 60:59 at 32,282 sizes each, near-squares pushed to the edge of the cap. Only 98,195 sizes (3.03%) come out as a fully reduced ratio that never touched the cap, and 1,014,431 (31.275%) land more than 1% away from the ratio they actually are, the worst by 8.329%.
Two things follow. The ratio you want and the ratio the tool writes are different objects: at their own pixel sizes, 10 of 15 common ratios came back verbatim and 13 were numerically exact, the worst being 1.91:1 written as 60:31, off by 1.334%. And one ratio can be written two ways depending on the pixel numbers: 21:9 came out as 7:3 from 2520 × 1080 and as 60:25 from 2560 × 1080.
None of that stops you writing the ratio you actually want. Five ways of saying it went into all 480 lines, each at the front of the line with a comma behind it:
| What you write | Own term | Weight read back | Out of range | Round trip | Tool’s words intact |
|---|---|---|---|---|---|
16:9 aspect ratio | 480/480 | 1 | 120 → 120 | 360 → 360 | 480/480 |
1.85:1 aspect ratio | 480/480 | 1 | 120 → 120 | 360 → 360 | 480/480 |
4:5 aspect | 480/480 | 1 | 120 → 120 | 360 → 360 | 480/480 |
widescreen, roughly sixteen by nine | 0/480 | — | 120 → 120 | 360 → 360 | 480/480 |
shot at 16:9 | 0/480 | 9 | 120 → 600 | 360 → 0 | 480/480 |
The first three are safe in every shape at every length, and the tool’s own wording survives all 480 lines byte for byte in every row. The fourth fails for a structural reason rather than a dangerous one: the comma inside your own phrase is a separator here, so it becomes two terms. The fifth is the colon from the section above, arriving on a different word: the parser reads shot at 16:9 as the term shot at 16 at weight 9, on 480 of 480 lines, which is why the round-trip count falls from 360 to 0. If you want a ratio in your own words, put it in the middle of the phrase, not at the end of it.
The camera: absent from the tool, safe to add, and one punctuation habit to drop
Nothing in the pipeline has a camera in it. The line carries a light reading, a sharpness reading and two brightness-distribution readings, and no field for a lens, a focal length, an aperture or a film speed. That makes the camera entirely yours to write — and it goes in cleanly. Six camera clauses, each inserted at the front of all 480 lines with a comma behind:
| What you write | Own term | Weight | Out of range | Round trip | Share of the new line |
|---|---|---|---|---|---|
shot on 85mm | 480/480 | 1 | 120 → 120 | 360 → 360 | 5.2% (3.2–11.5%) |
f/1.8 | 480/480 | 1 | 120 → 120 | 360 → 360 | 2.2% (1.4–5.2%) |
ISO 400 | 480/480 | 1 | 120 → 120 | 360 → 360 | 3.1% (1.9–7.1%) |
1/250 s | 480/480 | 1 | 120 → 120 | 360 → 360 | 3.1% (1.9–7.1%) |
85mm lens, f/2.0 | 480/480 | 1 | 120 → 120 | 360 → 360 | 6.8% (4.3–14.8%) |
shot on 35mm film | 480/480 | 1 | 120 → 120 | 360 → 360 | 7.2% (4.5–15.6%) |
Every one came back as its own term at weight 1 on 480 of 480 lines, with the tool’s own wording preserved byte for byte and the round-trip count unchanged from the baseline. The price is small: a camera clause is 2.2% to 7.2% of the finished line at the median, and the heaviest case in the whole run — the longest clause on the shortest line — was 15.6%.
The one habit to drop is writing settings with a colon. A colon followed by a number at the end of a term is a weight, so aperture:1.8 is read as the term aperture at weight 1.8, outside the 0.4–1.6 band, and ISO:400 is read as ISO at weight 400. Put a space after the colon, or leave it out entirely, and both read as 1:
aperture:1.8 -> aperture @ 1.8 out of range 1 round trip: no aperture: 1.8 -> aperture: 1.8 @ 1 out of range 0 round trip: yes ISO:400 -> ISO @ 400 out of range 1 round trip: no ISO 400 -> ISO 400 @ 1 out of range 0 round trip: yes f/1.8 -> f/1.8 @ 1 out of range 0 round trip: yes 1/250 s -> 1/250 s @ 1 out of range 0 round trip: yes 85mm -> 85mm @ 1 out of range 0 round trip: yes
So of the three: the structure you inherit and cannot reorder, the ratio you either accept or override in words, and the camera you supply from scratch. Only the second has a way of being misread, and it is the same colon that misreads a ratio anywhere else in the line.
What the 12,688 insertions were run on
Everything above comes from the same forty files: 39 photographs at 640 × 360 and one code screenshot at 800 × 450, decoded on this machine, box-downsampled to 192 × 192, and composed into four shapes at three lengths — 480 lines. The clause boundaries were rebuilt from src/compose.js and matched the real output on all 480 lines, so each insertion landed at a genuine position. Each of the 12,688 results was read back with this site’s own weight parser, the same one its checker uses. The three sections on structure, ratio and camera add 5,280 clause insertions — eleven clauses × 480 lines, each at the front with a comma behind — plus 3,243,601 size probes through the same aspect function, twelve hand-written prompts read back with the same parser, and seven settings written with and without a colon. No model was called and no image was generated at any point.
What should survive from this is short. The tool’s half of a picture prompt is a measurement, it arrives in a fixed order, and it is not going to change to accommodate your sentence — the pipeline never reads what you typed. Your half is one comma away from being clean wherever you put it, and one colon away from being misread as a weight. For the five edits people actually make to a generated line and what each one does to it, see what five edits do to a generated line; for the nine numbers behind the clauses you are editing around, see what this tool measures; and for what the finished line is, before you add anything to it, see what a picture prompt is.