Create an image collage layout
The image collage layout calculator turns a row-major list of image dimensions into a complete grid geometry.
Run — free
It finds the width required by each column and the height required by each row, then returns the collage canvas size and the exact rectangle for every cell. Use the result to place images accurately in HTML, canvas, SVG, design tools, or an image-processing pipeline without manually accumulating offsets or risking overlapping cells.
Prepare dimensions in row-major order
Supply one width and height pair for every image, ordered from left to right across the first row, then left to right across the next row, and so on. The rows and cols fields define the grid shape, so their product must equal the number of image records exactly. This strict count check prevents a common collage bug: silently leaving a blank cell or dropping an extra image because the intended shape and the source list disagree. Widths and heights must be positive finite numbers. They may be integers or decimals, which makes the calculator suitable for pixels, points, millimetres, or any other consistent unit. Do not mix units within one request, because the algorithm treats every number as part of the same coordinate system. The response preserves each source width and height alongside its calculated cell, making it straightforward to associate the layout entry with the original image and decide how that image should be fitted, cropped, or aligned later.
Understand how cell sizes are calculated
Each column is assigned the greatest source width found in that column, and each row is assigned the greatest source height found in that row. Every cell at their intersection therefore has the column width and row height, creating aligned grid boundaries while ensuring that each source image can fit inside its cell at its original dimensions. The calculator then builds x offsets by summing all earlier column widths and y offsets by summing all earlier row heights. The first cell begins at zero, zero. The total collage width is the sum of column widths, while the total height is the sum of row heights. This approach produces a compact rectangular grid without inventing a target canvas size or resizing policy. It deliberately calculates geometry only: it does not stretch, crop, rotate, or center an image. Those presentation choices can be applied afterward, using the returned cell rectangle and the preserved image dimensions as reliable inputs.
Use the result in a rendering pipeline
Read the cells array in the same order as the input images. Each entry includes its zero-based index, row and column, x and y origin, cell width and height, and original image width and height. A canvas renderer can draw into each returned rectangle; a CSS generator can convert the column_widths and row_heights arrays into explicit grid tracks; and an SVG builder can create clipping rectangles before inserting image elements. Because the output is deterministic and contains no environment-dependent values, the same request produces identical geometry in a browser, a build process, or an API workflow. If you want images centered without scaling, subtract the original dimensions from the cell dimensions and divide each difference by two. If you want cover or contain behavior, compute the scale from the cell and image aspect ratios. Keeping those policies separate makes this layout useful across many visual styles while leaving the grid calculation predictable, inspectable, and easy to test.
What you can do with it
Build a canvas photo collage
Calculate non-overlapping destination rectangles before drawing a collection of differently sized images onto one canvas.
Generate explicit CSS grid tracks
Turn the returned column widths and row heights into a grid template that matches the largest image in each track.
Plan an SVG contact sheet
Create cell rectangles and a total view box before adding image elements, labels, clipping paths, or borders.
FAQ
What does it cost?
Each API request costs $0.002. The calculation is also suitable for execution in the browser.
How are column widths chosen?
A column uses the largest source image width found among the images assigned to that column.
How are row heights chosen?
A row uses the largest source image height found among the images assigned to that row.
Does the calculator resize or crop images?
No. It calculates cell geometry and preserves source dimensions. Resizing, cropping, centering, and alignment are separate rendering decisions.
What happens when the image count does not match the grid?
The request fails with an invalid input error stating that the image count must equal rows multiplied by cols.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/image/collage-layout \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"images":[{"width":640,"height":480},{"width":800,"height":600},{"width":500,"height":700},{"width":720,"height":540}],"rows":2,"cols":2}'const res = await fetch("https://api.kit.forhosting.com/image/collage-layout", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"images": [
{
"width": 640,
"height": 480
},
{
"width": 800,
"height": 600
},
{
"width": 500,
"height": 700
},
{
"width": 720,
"height": 540
}
],
"rows": 2,
"cols": 2
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/collage-layout",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"images": [
{
"width": 640,
"height": 480
},
{
"width": 800,
"height": 600
},
{
"width": 500,
"height": 700
},
{
"width": 720,
"height": 540
}
],
"rows": 2,
"cols": 2
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/collage-layout", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"images":[{"width":640,"height":480},{"width":800,"height":600},{"width":500,"height":700},{"width":720,"height":540}],"rows":2,"cols":2}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"images":[{"width":640,"height":480},{"width":800,"height":600},{"width":500,"height":700},{"width":720,"height":540}],"rows":2,"cols":2}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/collage-layout", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"images": [
{
"width": 640,
"height": 480
},
{
"width": 800,
"height": 600
},
{
"width": 500,
"height": 700
},
{
"width": 720,
"height": 540
}
],
"rows": 2,
"cols": 2
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.collage_layout",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 15 |
max_megapixels | 12 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |