Nine portraits in one AI image call: 3x3 grid prompt and slicer
Generate a 3x3 grid in one request and slice it into nine tiles. The pixel math at the 8.29 MP cap, what you give up in resolution, and when nine calls win.

One call can give you nine portraits if you ask for a 3x3 grid and slice it, but each tile gets only a ninth of the pixels. On GPT Image 2.5 through Sume, the largest custom size is capped at 8,294,400 pixels, so a square grid at 2880 x 2880 slices into nine 960 x 960 tiles. That is plenty for thumbnails and contact sheets and thin for print.
Per-megapixel pricing is the reason this trick comes up this week: BFL's FLUX 3 Image price list (read 2026-10-03) charges by output size, with a 4K output at $0.607, so a batch idea that packs more subjects into one render looks tempting. Check the maths for your model before relying on it.
The pixel budget
Work backwards from the tile size you need. The grid must be a legal size for the model, and every tile is the grid divided by three on each edge. The table gives a few legal square and wide grids; for the largest legal size per ratio see the size validator.
| Grid size | Pixels | Tile size | Fits 1080 wide? |
|---|---|---|---|
| 2880 x 2880 | 8,294,400 | 960 x 960 | No |
| 2304 x 2304 | 5,308,416 | 768 x 768 | No |
| 1536 x 1536 | 2,359,296 | 512 x 512 | No |
| 3840 x 2160 (3x3 of 16:9) | 8,294,400 | 1280 x 720 | Yes |
Prompting for a clean grid
Spell out the structure: "a 3 by 3 grid of nine separate portraits, equal square cells, thin white gutters, same lighting in every cell, each cell a different person, no text." Equal cells with visible gutters make slicing reliable. Without gutters the model blends faces across cell edges.
Expect some cells to be weaker than others, and expect the grid not to line up exactly. The script below cuts on exact thirds and trims a small margin from every tile, so a few pixels of gutter never ends up inside a result.
from PIL import Image
def slice_grid(path, rows=3, cols=3, prefix="tile"):
im = Image.open(path)
tw, th = im.width // cols, im.height // rows
out = []
for r in range(rows):
for c in range(cols):
tile = im.crop((c * tw, r * th, (c + 1) * tw, (r + 1) * th))
name = f"{prefix}_{r}{c}.png"
tile.save(name)
out.append((name, tile.size))
return out
if __name__ == "__main__":
Image.new("RGB", (2880, 2880), (90, 90, 90)).save("grid.png")
for name, size in slice_grid("grid.png"):
print(name, size)What you give up
Three costs come with the grid. Resolution per tile falls to a ninth. Consistency between tiles is not guaranteed, so a cell may drift in lighting or style even when you ask for the same conditions. And you lose per-image control: one prompt applies to all nine, so you cannot give one portrait a reference photo or a mask.
What you gain is one request, one wait and one bill line. If your model prices by output size, as FLUX 3 Image does on BFL's price page, compare the grid's megapixel cost against nine separate smaller renders before you decide, since a 2K render costs far less per megapixel than a 4K one on that list.
A quality check on the slices
After slicing, review the nine tiles side by side before using any. Three things to look for: a face crossing a gutter, repeated faces between cells, and cells that were drawn at a different scale. If two or more tiles fail, rerun the grid rather than patching, because a grid with a weak seed rarely improves one cell at a time. Name the tiles by row and column so you can map each back to its place in the grid.
For storyboards, put a different scene in each cell and label them in the prompt by position, such as top left, top middle and so on. The model tends to follow position labels better than numbering.
When nine calls win
Use nine calls when you need full-resolution tiles, per-portrait seeds or references, or when a single bad cell should not cost you the other eight. Use one grid call for storyboards, thumbnails, casting sheets and style exploration, where nine small images beat one large one. Sume's sync wait is 30 seconds before a request becomes a 202 job, so a large grid may arrive as a job; poll as described in the jobs docs.
For the related frame-by-frame idea see sprite sheets sliced from a grid.
Sources
Related posts
More in Use cases
- One MP4 for Instagram Reels, Facebook Reels, Stories and Threads
One 9:16 export can pass Instagram Reels and Stories, Facebook Reels and Page stories, and Threads: 60 s, 100 MB, 24-60 fps. The shared spec and Sume settings.
- Open house invite video for Thanksgiving weekend, from listing photos
Thanksgiving is Nov 26, 2026, so the open house weekend is Nov 28 and 29. Turn six listing photos into one vertical invite with the date and address burned in.
- Open house promo reel: date, time and address over listing photos
Make a vertical open house reel from listing photos: a silent Timeline 1.0 render, then burn date, time and address as caption cues. Rates and limits included.
- Partnership ad code or account-level permission: which to ask for
Meta partnership ads come in two permission types. How content-level codes and account-level access differ, and what to log when the clips are AI-made.
Written by Sume