What one image to prompt line can carry into another shape
Twenty of the thirty-six possible rewrites are exact, and the other sixteen are not approximate — they cannot be done. One image, four output shapes, three lengths: 12 lines per file. Between any two shapes there are 12 ordered pairs, and at each of the three lengths that is 36 possible rewrites. I ran all of them on forty real files, working only from the finished line — never going back to the image. The result splits cleanly in two, with nothing in between:
- Twenty rewrites are exact on all forty files. Not “close”. The rewritten line is byte-identical to the line the tool produces from the picture itself, 40 of 40 times, in every one of those twenty cells.
- Sixteen rewrites are impossible on all forty files. In each case the reason is a specific value the source line never wrote: the aspect parameter, the contrast clause, the distribution clause, or the vertical clause. No amount of clever wording recovers a value that was never in the line.
- The direction matters more than the pair. A Midjourney line can be rewritten into all three other shapes at all three lengths — 9 of 9 cells. No line of any other shape can be rewritten into a Midjourney line, because
--arappears in no other shape’s output.
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 the 192 × 192 grid the live tool measures on, and composed into four shapes at three lengths: 480 lines, twelve per file. Then, for each ordered pair of shapes and each length, a translator was given only the source line as a string. It had no access to the picture, the grid or the measurements. It pulled the values out of the line using the closed vocabulary in src/describe.js, re-rendered them with the target shape’s template from src/compose.js, and the result was compared byte for byte against the line the tool generates from the picture. No model was called and no image was generated. Everything below is in prep/day30-translate.json and prep/day30-b.json in this workspace.
Twelve values, and which of the four lines carries them
Before you can ask whether a line can be rewritten, you have to ask what a line is carrying. The measurement produces a fixed set of values — framing, exposure, saturation, temperature, contrast, detail, distribution, vertical, mood, the palette words, the monochrome subject, and the aspect parameter. Twelve in all. Each shape writes some of them and leaves others out, and the ones left out are exactly what makes a rewrite impossible.
| Value | Midjourney | Stable Diffusion | Flux | DALL·E |
|---|---|---|---|---|
| Framing | 40 | 40 | 40 | 40 |
| Exposure | 40 | 40 | 40 | 40 |
| Saturation | 40 | 40 | 40 | 40 |
| Temperature | 40 | 40 | 40 | 40 |
| Contrast | 40 | 40 | 0 | 0 |
| Detail | 40 | 40 | 40 | 40 |
| Distribution | 40 | 40 | 40 | 0 |
| Vertical | 28 | 28 | 0 | 0 |
| Mood | 40 | 40 | 40 | 40 |
| Palette words | 40 | 40 | 40 | 40 |
| Subject (monochrome) | 4 | 4 | 4 | 4 |
| Aspect parameter | 40 | 0 | 0 | 0 |
Three rows decide everything that follows. Contrast is written by the two tag shapes and by neither sentence shape. Distribution is written by three shapes and never by DALL·E. And the aspect parameter is written by exactly one shape, Midjourney, in the --ar flag at the end of the line. Nothing else in any output carries it.
Length moves the same lever inside a shape, because src/compose.js gates whole clauses on it. At the short length the two sentence shapes drop saturation and temperature entirely — they first appear at medium. So the count of values a line carries ranges from three to twelve:
| Shape | Short | Medium | Long |
|---|---|---|---|
| Midjourney | 6–7 (median 6) | 9–10 (median 9) | 10–12 (median 11) |
| Stable Diffusion | 5–6 (median 5) | 8–9 (median 8) | 9–11 (median 10) |
| Flux | 3–4 (median 3) | 6–7 (median 6) | 8–9 (median 8) |
| DALL·E | 3–4 (median 3) | 6–7 (median 6) | 7–8 (median 7) |
The thirty-six rewrites: twenty exact, sixteen impossible
The rule is short: a line can be rewritten into another shape if, and only if, it already carries every value that shape reads. Nothing else matters — not the wording, not the punctuation, not the length of the line. Here is all thirty-six, at each of the three lengths.
| From → to | Short | Medium | Long |
|---|---|---|---|
| Midjourney → Stable Diffusion | exact 40/40 | exact 40/40 | exact 40/40 |
| Midjourney → Flux | exact 40/40 | exact 40/40 | exact 40/40 |
| Midjourney → DALL·E | exact 40/40 | exact 40/40 | exact 40/40 |
| Stable Diffusion → Flux | exact 40/40 | exact 40/40 | exact 40/40 |
| Stable Diffusion → DALL·E | exact 40/40 | exact 40/40 | exact 40/40 |
| Flux → DALL·E | exact 40/40 | exact 40/40 | exact 40/40 |
| DALL·E → Flux | exact 40/40 | exact 40/40 | no — distribution missing |
| Stable Diffusion → Midjourney | no — aspect missing | no — aspect missing | no — aspect missing |
| Flux → Midjourney | no — saturation, temperature, aspect | no — contrast, distribution, aspect | no — contrast, aspect, vertical on 28 files |
| Flux → Stable Diffusion | no — saturation, temperature | no — contrast, distribution | no — contrast, vertical on 28 files |
| DALL·E → Midjourney | no — saturation, temperature, aspect | no — contrast, distribution, aspect | no — contrast, distribution, aspect, vertical on 28 files |
| DALL·E → Stable Diffusion | no — saturation, temperature | no — contrast, distribution | no — contrast, distribution, vertical on 28 files |
Two things in that table are worth slowing down on. The first is how absolute the split is: there is no cell where the rewrite works on some files and fails on others. A missing value is missing on all forty, because the shape never writes it. The second is the one asymmetry: Flux → DALL·E works at every length, but DALL·E → Flux fails at long and only at long. The long Flux line needs the distribution clause, and DALL·E is the one shape that never writes it.
Why no line can become a Midjourney line
Add up the table a different way. Of the 480 lines, how many could be rebuilt from another shape’s line on the same picture? 360 of 480. Broken down by target shape: Stable Diffusion 120 of 120, Flux 120 of 120, DALL·E 120 of 120, and Midjourney 0 of 120.
Every Midjourney line is unreachable, and the reason is one value. src/compose.js appends ’ --ar ’ + m.arParam to the Midjourney line and to no other. The aspect parameter is computed in src/palette.js by taking the greatest common divisor of the file’s width and height and capping the result at 60 — a piece of arithmetic on the file’s dimensions that no measurement on the 192 × 192 grid can reproduce. So the three other shapes, which carry the framing phrase but not the aspect parameter, cannot supply it.
It is tempting to read the framing phrase as a substitute: on these forty files the framing value is widescreen 16:9 and the aspect parameter is 16:9, on all 40. Do not. Those two strings come from two independent code paths — the framing phrase is a threshold bucket over the measured ratio, the aspect parameter is integer arithmetic over the original dimensions — and they can disagree. The bucket says what kind of frame it is; the parameter says what to ask the generator for. Only one of them is in the line.
What carries over: the payload, not the words
Strip both lines down to the values they share and ask how much of each line that is. This separates two things that are easy to confuse: whether the information survives a rewrite, and whether the wording does. They are not the same number.
| Pair | Shared payload, share of the first line | Shared payload, share of the second | Shared words (Jaccard) |
|---|---|---|---|
| Midjourney ↔ Stable Diffusion | 80.1% | 75.8% | 89.7% |
| Midjourney ↔ Flux | 70.6% | 80.5% | 46.6% |
| Midjourney ↔ DALL·E | 63.3% | 82.3% | 53.6% |
| Stable Diffusion ↔ Flux | 67.0% | 80.5% | 44.7% |
| Stable Diffusion ↔ DALL·E | 59.7% | 82.3% | 51.1% |
| Flux ↔ DALL·E | 71.4% | 82.3% | 58.3% |
Read the last column against the first two. Between Midjourney and Flux, roughly 70–80% of each line’s characters are shared values, yet fewer than half the distinct words are common to both. That gap is the rewrite: the same handful of measurements, wearing completely different sentences. It is also why a rewrite done by hand, by swapping words one at a time, is the slow way to do it — you are editing the part that does not survive while the part that does survive sits untouched.
The same four lines can be taken apart slot by slot instead of word by word, which is what tells you which readings a shape quietly drops and how many characters of measurement that costs you: see how much of a prompt survives when the same picture is written for four different models.
Here is one file, all four shapes at the long length, verbatim:
[midjourney] widescreen 16:9 composition, well-lit, balanced exposure, dominant palette of white, charcoal, silver, grey, muted, desaturated tones, neutral colour temperature, high contrast, moderate detail and texture, evenly lit, brighter upper half, moody and dramatic atmosphere --ar 16:9 [sd] masterpiece, best quality, widescreen 16:9 composition, well-lit, balanced exposure, dominant palette of white, charcoal, silver, grey, muted, desaturated tones, neutral colour temperature, high contrast, moderate detail and texture, evenly lit, brighter upper half, moody and dramatic atmosphere [flux] A widescreen 16:9 image. Well-lit, balanced exposure. The dominant colours are white, charcoal, silver, grey. Muted, desaturated tones, neutral colour temperature. Moderate detail and texture. Evenly lit. Moody and dramatic atmosphere. [dalle] A widescreen 16:9 image, well-lit, balanced exposure, with a palette of white, charcoal, silver, grey. Muted, desaturated tones, neutral colour temperature, moderate detail and texture. Moody and dramatic atmosphere.
Four lines, 300.5 / 317.5 / 261.5 / 222 characters in the median file, and one set of measurements underneath them. The palette clause is the clearest case: dominant palette of white, charcoal, silver, grey, The dominant colours are white, charcoal, silver, grey. and with a palette of white, charcoal, silver, grey. — three wrappers around four identical words in the same order. Translating it means replacing eleven characters, not re-reading anything.
Where the order holds, and the four files where it does not
Take the values two lines have in common and compare the order they appear in. Across 12 ordered pairs, 3 lengths and 40 files — 1,440 comparisons — 1,344 come out with no inversion at all. The remaining 96 have exactly 2, and 2 is the largest number seen anywhere.
Those 96 are not scattered. They are 24 cells — the eight ordered pairs that cross between a tag shape and a sentence shape, at each of the three lengths — times the 4 files on which the monochrome clause fires. Every other file, including all 36 non-monochrome ones, comes out clean in every direction.
| Pair | Short common / worst | Medium common / worst | Long common / worst |
|---|---|---|---|
| Midjourney ↔ Stable Diffusion | 5 / 0 | 8 / 0 | 10 / 0 |
| Flux ↔ DALL·E | 3 / 0 | 6 / 0 | 7 / 0 |
| Midjourney ↔ Flux | 3 / 2 | 6 / 2 | 8 / 2 |
| Midjourney ↔ DALL·E | 3 / 2 | 6 / 2 | 7 / 2 |
| Stable Diffusion ↔ Flux | 3 / 2 | 6 / 2 | 8 / 2 |
| Stable Diffusion ↔ DALL·E | 3 / 2 | 6 / 2 | 7 / 2 |
The reason is one line of src/compose.js. Both tag shapes build a core array and then splice the palette clause in at index 2 — a fixed position, not a named slot. On a colour file core starts framing, exposure, saturation, so index 2 falls between exposure and saturation, and the palette lands after exposure, which is exactly where the two sentence shapes put it. On a monochrome file core gains the subject clause at the front, so it starts subject, framing, exposure, and the same index 2 now falls between framing and exposure. Two things move at once: the palette clause jumps ahead of exposure, and the subject clause sits ahead of framing. Hence two inversions, on those four files only.
So the practical version is: a rewrite never has to reorder anything on a colour file, and on the rare monochrome file it has to move two clauses — the subject clause to the front and the palette clause ahead of exposure. Everything else keeps its position, because the sentence shapes walk the same core array in the same order and merely skip the entries they do not want.
How to rewrite a line by hand
You do not need the tool for this, and you do not need the picture either — provided you start from a line that carries what the target needs.
- Start from the longest line you have. Length is what carries values. A short Flux or DALL·E line carries 3 of the twelve and cannot be rewritten into anything but another sentence shape; a long Midjourney line carries 11 and can be rewritten into all three others.
- Pull the values out, not the words. Every phrase in the line is one entry from a closed table in
src/describe.js. Match the line against that table and keep the entries; discard the commas, the periods, the--arflag and the wrappers. - List what the target shape reads. Contrast and distribution are the two that catch people out: the two sentence shapes never read contrast, and DALL·E never reads distribution. If the target reads a value your source line does not contain, stop — the rewrite cannot be done from the line alone.
- Re-render with the target’s template and keep the order. Same sequence, new wrapper — with the one exception above, if the file is monochrome. In every one of the twenty cells where the values were present, this produced a line byte-identical to the one the tool would have generated from the picture, 40 of 40 files.
- If a value is genuinely missing, go back to the file. There is no inference that recovers it. Re-running the tool on the picture costs one drop; guessing costs a clause that is wrong in a way you cannot detect from the line.
Here is the same file at the short length, where the sentence shapes are at their thinnest. These four lines carry 6, 5, 3 and 3 of the twelve values respectively, and the two short sentence lines are missing saturation and temperature outright:
[midjourney/short] widescreen 16:9 composition, well-lit, balanced exposure, dominant palette of white, charcoal, silver, grey, muted, desaturated tones, neutral colour temperature --ar 16:9 [sd/short] masterpiece, best quality, widescreen 16:9 composition, well-lit, balanced exposure, dominant palette of white, charcoal, silver, grey, muted, desaturated tones, neutral colour temperature [flux/short] A widescreen 16:9 image. Well-lit, balanced exposure. The dominant colours are white, charcoal, silver, grey. [dalle/short] A widescreen 16:9 image, well-lit, balanced exposure, with a palette of white, charcoal, silver, grey.
Forty files, 480 lines, thirty-six rewrites, and one value only Midjourney writes
Strip it to what is measurable. Four shapes, three lengths, forty files, 480 lines. Between shapes there are 36 rewrites to attempt; 20 succeed exactly on every file and 16 fail on every file, and which is which is decided entirely by whether the source line already carries the values the target reads — never by how the line is worded.
What survives a rewrite is the payload and the order: 59.7–82.3% of a long line’s characters are shared values, and the relative order of those values holds in 1,344 of 1,440 comparisons, with the 96 exceptions all being the same two swaps on the same four monochrome files. What does not survive is the wording, which is why the shared-word overlap between a tag shape and a sentence shape sits at 44.7–53.6% while the shared payload on those same pairs runs from 59.7% to 82.3%.
And the one value that breaks the symmetry is the aspect parameter, written by Midjourney alone. That single line of src/compose.js is why 360 of the 480 lines can be rebuilt from a sibling line and 120 — every Midjourney line — cannot. If you work across shapes, keep the Midjourney line as your source of record. It is the only one that carries everything.
Every number above traces back to a threshold you can argue with. For the nine measurements behind the twelve values and where each threshold sits, see what this tool measures on your image. For the shape those values get written into when the target is Midjourney, including where the aspect parameter comes from, see what a Midjourney prompt looks like when it comes out of a photograph. For the sentence shape on the other side of the widest gap in the table above, see how a Flux prompt is built out of sentences.