visualtoprompt.com

A Grok image prompt from an image: seven fields, one you can fill

A Grok Imagine image request takes seven fields. Six of them are settings — model, count, shape, size, quality, output format — and one, prompt, carries the content. A prompt generated from your picture fills that one completely. Of the other six it can supply exactly one, the shape, and only from the Midjourney output: 3 of 12 real outputs, and even then it writes the shape into the prompt text rather than into the field it belongs in.

Seven field names on one side, twelve measured values on the other, and not one name in common. That gap is the whole subject of this page. It also means the tool on the front page cannot write a Grok request at all: its generator emits four shapes — Midjourney, Stable Diffusion, Flux, DALL·E — and Grok Imagine is none of them. Nothing below is a Grok prompt the tool produced. No request went to an API and no picture came back; what follows is the part you still type by hand once the line exists.

Here is the whole page in four numbers. The request has 7 fields, of which 1 carries content. The tool’s describer writes 12 named values, of which 11 reach the prompt. Across 12 real outputs the tool named the model 0 times, the size 0 times, the count 0 times, and the shape 3 times. And of Grok’s fifteen ratio values, 3 are strings the tool can never produce at any size.

Seven fields against twelve values

The two sides are counted differently, which is the reason they do not meet in the middle. A Grok request has seven names in it: model, prompt, n, aspect_ratio, resolution, quality, response_format. Only prompt is a description of anything. Everything else is an instruction about how to render.

On this side, src/describe.js assigns 12 named values — framing, exposure, contrast, saturation, temperature, detail, light distribution, vertical bias, the palette words, a subject, a hint, and a mood. compose.js reads 11 of them. The one it never reads is hint, which is computed on every pass and dropped on every pass.

Both sides counted from source: src/describe.js and src/compose.js on this site, the field list from xAI’s published image generation reference.
Grok request fieldWhat it holdsSupplied by a generated prompt?
modelwhich model renders it0 / 12
promptthe description12 / 12
nhow many images, 1–100 / 12
aspect_ratioone of 15 values, or auto3 / 12
resolution1k or 2k0 / 12
qualitylow, medium or auto0 / 12
response_formaturl or b64_json0 / 12

So the description travels intact and the settings do not travel at all. That is not a defect in either side; a prompt generated from a picture is a description of that picture, and every one of those six names is a decision about an output that does not exist yet.

On a target that takes the picture as well as the words, the same exercise measures something else: a Gemini image prompt carries eight fields, and the picture arrives as a second part of the same request that no generated line can supply. There the question is not which of the settings travel, but how much of what you send the words actually are.

Three of the fifteen ratios the tool can never write

Grok’s aspect_ratio accepts fifteen numeric values plus auto: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 2:1, 1:2, 19.5:9, 9:19.5, 20:9, 9:20, 21:9, 5:2. This tool computes its ratio arithmetically instead of picking from a list — greatest common divisor, then a cap of 60 — so the question is not whether the numbers match but whether the strings do.

Sweeping every width and height from 200 to 4000 finds 14,305 size pairs whose real ratio is exactly one of those fifteen. In 13,252 of them the tool writes the official string. In the remaining 1,053 — 7.36% — it does not.

Every width/height pair from 200×200 to 4000×4000, compared to the fifteen values. “Written differently” counts pairs where the true ratio is the tier but the string is not.
RatioSizes that really are itWritten identicallyWritten differentlyThe tool writes
1:13,8013,8010—
16:92282280—
9:162282280—
4:39349340—
3:49349340—
3:21,2341,2340—
2:31,2341,2340—
2:11,8011,8010—
1:21,8011,8010—
19.5:9274027413:6
9:19.527402746:13
20:91781780—
9:201781780—
21:950505057:3 or 60:25
5:27017010—

The three that fail fail for two different reasons, and the difference matters when you fix them by hand. 19.5:9 and 9:19.5 are the same numbers as 13:6 and 6:13 — a decimal in the official name, and a fraction this tool always reduces to whole numbers. 21:9 is different: it reduces too, because the greatest common divisor of 21 and 9 is 3, so it comes out as 7:3. At larger sizes the 60-cap takes over instead and the same ratio comes out as 60:25.

What the tool writes, size by size

One synthetic gradient — the same normalised picture at every size, only the file dimensions changed — run through the Midjourney shape, which is the only shape that carries a ratio at all.

Size probe: one picture, fifteen sizes, Midjourney shape at long length. “Match” asks whether the --ar tail is itself one of the fifteen allowed strings.
Requested ratioSize fed in--ar tailMatchFraming phrase
1:11024 × 10241:1Yessquare 1:1
16:91920 × 108016:9Yeswidescreen 16:9
9:161080 × 19209:16Yesportrait 2:3
4:31600 × 12004:3Yesnear-square 4:3
3:41200 × 16003:4Yesportrait 3:4
3:21800 × 12003:2Yeslandscape 3:2
2:31200 × 18002:3Yesportrait 2:3
2:12000 × 10002:1Yeswidescreen 16:9
1:21000 × 20001:2Yestall vertical 9:16
19.5:91950 × 90013:6Nowidescreen 16:9
9:19.5900 × 19506:13Notall vertical 9:16
20:92000 × 90020:9Yesultra-wide panoramic
9:20900 × 20009:20Yestall vertical 9:16
21:92560 × 108060:25Noultra-wide panoramic
5:22000 × 8005:2Yesultra-wide panoramic

12 of 15 come out as strings the field accepts. Note the two that disagree with themselves: 9:16 is described as “portrait 2:3”, and 1:2 as “tall vertical 9:16”. The framing phrase is a bucket cut by thresholds in src/describe.js; the ratio is arithmetic in src/palette.js. They are two independent code paths and they are not obliged to agree.

The shape is in the string; the field is outside it

Even when the tool does produce a usable ratio, it produces it in the wrong place. On the three pictures this site keeps in rotation, all nine Midjourney outputs end with the same ten characters.

Three pictures, three length settings, Midjourney shape. The tail is the last ten characters of every line.
PictureLengthWhole lineTailShareLine without it
night fireworksshort163--ar 16:9 / 106.1%153
medium267--ar 16:9 / 103.7%257
long319--ar 16:9 / 103.1%309
strong backlightshort158--ar 16:9 / 106.3%148
medium239--ar 16:9 / 104.2%229
long291--ar 16:9 / 103.4%281
text screenshotshort167--ar 16:9 / 106.0%157
medium235--ar 16:9 / 104.3%225
long266--ar 16:9 / 103.8%256

All nine tails read 16:9, which happens to be an allowed value — so the fix is a cut, not a conversion: delete the last ten characters and put "aspect_ratio": "16:9" next to the prompt instead. Left in place, those ten characters are read as ordinary English words sitting at the end of your description, because nothing in the request parses prompt syntax.

For the other three shapes there is nothing to move. Flux and DALL·E write sentences and Stable Diffusion writes a comma list; none of the three carries any shape marker, which is why the shape count in the first table is 3 of 12 and not 12 of 12.

How much of the request is yours

Measured as JSON. The minimal request is model plus prompt and nothing else — every other field has a default. The pinned request is all seven. The settings block is 121 characters in all twelve cases; it does not vary, because none of it depends on the picture.

{
  "model": "grok-imagine-image-2.0",
  "prompt": "widescreen 16:9 composition, dark, low-key lighting, dominant palette of navy, grey, slate, silver, vivid, saturated colour, cool blue colour temperature, medium contrast, highly detailed with intricate texture, light falling on the centre with darker edges, brighter upper half, moody and dramatic atmosphere --ar 16:9",
  "n": 1,
  "aspect_ratio": "16:9",
  "resolution": "1k",
  "quality": "auto",
  "response_format": "url"
}
Twelve requests built from twelve real outputs — three pictures, four shapes, long length. Percentages are the prompt’s share of the finished request.
PictureShapePromptMinimal requestSharePinned requestShareShape field
night fireworksMidjourney31936587.4%45270.6%16:9
Stable Diffusion33638288.0%46971.6%not supplied
Flux27331985.6%40667.2%not supplied
DALL·E21926582.6%35262.2%not supplied
strong backlightMidjourney29133786.4%42468.6%16:9
Stable Diffusion30835487.0%44169.8%not supplied
Flux24729384.3%38065.0%not supplied
DALL·E20324981.5%33660.4%not supplied
text screenshotMidjourney26631285.3%39966.7%16:9
Stable Diffusion28332986.0%41668.0%not supplied
Flux23828483.8%37164.2%not supplied
DALL·E21926582.6%35262.2%not supplied

Read the two share columns against each other. In the minimal request the generated prompt is 81.5% to 88% of everything you send. Pin all six settings and it falls to 60.4% to 71.6% — the description is still the majority of the request, but a third of the remainder is six names that no picture can tell you.

Longer costs nothing here

xAI bills image generation per image rather than by prompt length, which makes the length setting a free variable on this target. Across all 36 outputs — three pictures, four shapes, three lengths — the long line is between 1.54× and 2.73× the short one, a spread of +99 to +173 characters.

All 36 outputs. Short range 93–184 characters, long range 203–336.
PictureShapeShortMediumLongLong / shortAdded
night fireworksMidjourney1632673191.96×+156
Stable Diffusion1802843361.87×+156
Flux1001952732.73×+173
DALL·E931882192.35×+126
strong backlightMidjourney1582392911.84×+133
Stable Diffusion1752563081.76×+133
Flux1051792472.35×+142
DALL·E981722032.07×+105
text screenshotMidjourney1672352661.59×+99
Stable Diffusion1842522831.54×+99
Flux1101952382.16×+128
DALL·E1031882192.13×+116

The two sentence shapes stretch the most, because each length step adds whole sentences rather than tags. That is the one place where a “which shape should I send” decision has a visible cost difference: the same picture costs you 93 characters or 336 depending on which of the four you pick.

Nothing in the line is syntax this target parses

Across the same 36 outputs: parentheses 0, square brackets 0, AND 0, the word negative 0. There are 45 colons and 9 double hyphens, and every one of them is a ratio — 36 inside the framing phrase “widescreen 16:9”, 9 in the Midjourney tails. Not one colon is a weight, because a weight needs a bracket to live in and there are no brackets.

That is the good news, and it is worth saying plainly: a generated line needs no translation to be legal here. There is no weighting grammar to strip and no negative-prompt slot to fill, because the tool writes neither. The work in this pair of pages is all about the six names around the prompt, not the prompt itself.

Eight buckets against fifteen values

Last comparison, and the one that catches people out: the framing phrase is a bucket, not a ratio. Sorted by which of the fifteen land in each of the eight phrases.

Each of Grok’s fifteen ratios run through the framing thresholds in src/describe.js.
Framing phraseValues coveredWhich
ultra-wide panoramic320:9, 21:9, 5:2
widescreen 16:9316:9, 2:1, 19.5:9
landscape 3:213:2
near-square 4:314:3
square 1:111:1
portrait 3:413:4
portrait 2:329:16, 2:3
tall vertical 9:1631:2, 9:19.5, 9:20

In 6 of the 15 the number in the phrase is not the ratio you asked for — 9:16 comes back as “portrait 2:3”, 1:2 and 9:20 as “tall vertical 9:16”, 2:1 and 19.5:9 as “widescreen 16:9”. If you were using the phrase to choose the field, you would pick wrong on six of fifteen. Take the ratio from the --ar tail, or from the size of your file — never from the words.

Six things to do before you send it

  1. Cut the last ten characters off the Midjourney line. It ends with  --ar 16:9 on every one of the nine outputs measured here. Put that value in aspect_ratio instead.
  2. Convert, do not copy, when the tail is 7:3, 60:25, 13:6 or 6:13. Those are 21:9, 21:9, 19.5:9 and 9:19.5. The numbers are already right; only the string is wrong.
  3. Name the resolution yourself. It is 1k or 2k and the tool supplies it 0 times out of 12. This tool measured your picture on a 192 × 192 grid — 36,864 cells — and never once wrote down how big the original was.
  4. Decide whether you want quality pinned. Left out, it is auto, and for generation auto currently resolves to low. That is a real choice being made for you.
  5. Do not bother shortening the line. Length is billed per image, so the +99 to +173 characters between short and long cost the same.
  6. Leave the weights alone — there are none. Zero parentheses across 36 outputs. If you want emphasis, add it yourself and add it in prose, not in syntax this target does not read.

Which side of the comparison each number sits on

Neither column was copied from the other. The right-hand side is xAI’s published image generation reference: the seven request fields, the fifteen ratio values plus auto, the two resolutions, the three quality values, and the n range of 1 to 10. That documentation is what the left column gets measured against, not a claim of its own. Every value on the left is printed by this repository as it runs here: src/palette.js for the gcd-and-cap ratio arithmetic, src/describe.js for the twelve values and the eight framing thresholds, src/compose.js for the four shapes, with three pictures sampled to 192 × 192 exactly as the live tool does. The ratio sweep covered every width and height from 200 to 4000; the fifteen-row size probe is one normalised gradient at fifteen sizes; the twelve requests are JSON built from twelve real outputs. No API was called and no image was generated.

For the shape that carries a ratio at all, see the Midjourney prompt; for the two sentence shapes, see the Flux prompt and the ChatGPT image prompt; for the same exercise against a different model’s field list, see the Nano Banana Pro prompt; and for what is lost before any of this, see where your image goes when it is measured.