VisualToPrompt

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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:9 is read as the term paper texture 16 at 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.

Every shape at every length, as rebuilt from src/compose.js and verified character for character on all 480 lines. “Slots” is the number of clauses; “places” is slots plus one, because you can also go at the very front and the very end. Ranges differ per file because two clauses are conditional: the subject clause only appears above a monochrome ratio of 0.85, and the vertical-light clause only when the measurement produces one.
ShapeLengthSlotsPlaces to put your wordsJoined withFixed piece
Midjourneyshort5–66–7commatail --ar 16:9
Midjourneymedium8–99–10commatail --ar 16:9
Midjourneylong9–1110–12commatail --ar 16:9
Stable Diffusionshort5–66–7commaprefix masterpiece, best quality,
Stable Diffusionmedium8–99–10commaprefix masterpiece, best quality,
Stable Diffusionlong9–1110–12commaprefix masterpiece, best quality,
Fluxshort3–44–5space—
Fluxmedium5–66–7space—
Fluxlong7–88–9space—
DALL·Eshort12space—
DALL·Emedium23space—
DALL·Elong34space—

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.

Share of insertions in which your phrase came back as its own piece — one term, nothing else stuck to it. “Comma behind” is your words, . “Comma both sides” is , your words, . “Space” is your words . “Period” is Your words. . Each cell is 40 files × the number of places for that shape and length; across all twelve rows that is 3,172 insertions per method, 12,688 in total.
ShapeLengthComma behindComma both sidesSpacePeriod
Midjourneyshort83.6%100%0%0%
Midjourneymedium89.0%100%0%0%
Midjourneylong90.7%100%0%0%
Stable Diffusionshort100%100%0%0%
Stable Diffusionmedium100%100%0%0%
Stable Diffusionlong100%100%0%0%
Fluxshort48.8%100%0%0%
Fluxmedium32.8%100%0%0%
Fluxlong24.7%100%0%0%
DALL·Eshort100%100%0%0%
DALL·Emedium66.7%100%0%0%
DALL·Elong50.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.

Median across 40 files, long setting. “Front” is the first gap, “last” is the final one, “all gaps” is the median over every gap on every file. Midjourney never reaches 100% because the --ar tail always follows; Stable Diffusion never starts at 0% because its quality prefix always precedes.
ShapeFrontLastAll gaps (median)Why the ends are not 0 and 100
Midjourney0%96.65%52.95%--ar 16:9 tail always follows your words
Stable Diffusion8.5%100%58.95%masterpiece, best quality, always precedes them
Flux0%100%52.30%—
DALL·E0%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.

One phrase inserted with a comma on both sides at the last clause boundary, long setting, 40 files × 4 shapes = 160 lines per row. “Share of the new line” is the median fraction of the finished line that is your words.
Words you writeCharacters addedShare of the new lineCame back as one termWeight
1+93.1%160/1601
2+175.8%160/1601
4+268.6%160/1601
8+5416.3%160/1601
17+9625.7%160/1601
27+15335.5%160/1601

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.

The same two-word phrase written five ways, inserted with a comma on both sides at the last clause boundary, long setting, 40 files × 4 shapes = 160 lines per row. “Out of range” counts terms outside the 0.4–1.6 band this site treats as usable. The 16:9 row adds one per line in all four shapes on top of the Midjourney baseline, hence 200 rather than 160.
What you writeWeight read backYour words still one termOut of range (of 160 lines)
paper texture1160/16040 (Midjourney baseline)
paper texture 16:990/160200
(paper texture)1.1160/16040 (Midjourney baseline)
[paper texture]0.9091160/16040 (Midjourney baseline)
(paper texture:1.4)1.4160/16040 (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.

Every shape at every length, over the same 40 files. “Line words” is minimum – median – maximum. “Groups” is how many distinct field orders exist and how many files fall in each — the groups are the subject and vertical-light conditions, and the order inside a group never differs. “Widest field” is the field whose word count swings most, with the words it swings between.
ShapeLengthLine wordsGroups (files each)Widest field
Midjourneyshort21 – 22 – 272 (36 / 4)palette, 3–6 words
Midjourneymedium29 – 34 – 412 (36 / 4)light distribution, 2–8 words
Midjourneylong33 – 39 – 454 (9 / 27 / 3 / 1)light distribution, 2–8 words
Stable Diffusionshort22 – 23 – 282 (36 / 4)palette, 3–6 words
Stable Diffusionmedium30 – 35 – 422 (36 / 4)light distribution, 2–8 words
Stable Diffusionlong34 – 40 – 464 (9 / 27 / 3 / 1)light distribution, 2–8 words
Fluxshort14 – 16 – 252 (36 / 4)palette, 3–6 words
Fluxmedium25 – 27 – 362 (36 / 4)light distribution, 2–8 words
Fluxlong31 – 36 – 472 (36 / 4)light distribution, 2–8 words
DALL·Eshort14 – 16 – 222 (36 / 4)palette, 3–6 words
DALL·Emedium25 – 27 – 332 (36 / 4)palette, 3–6 words
DALL·Elong29 – 31 – 362 (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:

One phrase inserted at the front of every one of the 480 lines, followed by a comma. “Own term” counts lines where the phrase came back as a term of its own. “Out of range” counts lines carrying a weight outside the 0.4–1.6 band; the baseline is 120 because every Midjourney line already carries one. “Round trip” counts lines that come back byte-identical from the explicit-weight writer; the baseline is 360 because Midjourney lines never do.
What you writeOwn termWeight read backOut of rangeRound tripTool’s words intact
16:9 aspect ratio480/4801120 → 120360 → 360480/480
1.85:1 aspect ratio480/4801120 → 120360 → 360480/480
4:5 aspect480/4801120 → 120360 → 360480/480
widescreen, roughly sixteen by nine0/480—120 → 120360 → 360480/480
shot at 16:90/4809120 → 600360 → 0480/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:

Same method as the table above: clause at the front of the line, comma behind it, 480 lines each. “Share of the new line” is the median, with the range across all 480 lines in brackets — the small percentages come from long lines and the large ones from short lines.
What you writeOwn termWeightOut of rangeRound tripShare of the new line
shot on 85mm480/4801120 → 120360 → 3605.2% (3.2–11.5%)
f/1.8480/4801120 → 120360 → 3602.2% (1.4–5.2%)
ISO 400480/4801120 → 120360 → 3603.1% (1.9–7.1%)
1/250 s480/4801120 → 120360 → 3603.1% (1.9–7.1%)
85mm lens, f/2.0480/4801120 → 120360 → 3606.8% (4.3–14.8%)
shot on 35mm film480/4801120 → 120360 → 3607.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.