Build a before-and-after image comparison layout
Create a precise before-and-after image comparison layout without guessing coordinates in UI code.
Run — free
Supply the pixel dimensions of both images, choose a side-by-side presentation or a slider overlay, and receive the canvas, image rectangles, clipping regions, and vertical divider position as structured data. Matching dimensions are expected because honest visual comparisons depend on aligned content. When your source images differ, you can explicitly request a resize instruction that maps the after image to the before image dimensions before display.
Choose the comparison format that fits the story
A before-and-after presentation can answer two different viewing needs. A side-by-side image comparison layout keeps each image completely visible, which is useful when readers need to scan the whole scene, compare distant areas, or view the result without interacting. The returned canvas is twice the effective image width, with the before panel on the left, the after panel on the right, and a vertical divider at their shared boundary. A slider overlay instead places both images in the same coordinate space. Its complementary clipping rectangles expose the before image to the left of the divider and the after image to the right. This format makes small changes easier to locate because matching features stay in the same place while the divider moves. Select the mode according to the audience and interface, then use the returned rectangles directly in CSS, SVG, Canvas, or a native rendering layer. Coordinates are integer pixels, so there is no hidden layout convention to reconstruct downstream.
Handle dimensions explicitly instead of hiding mismatches
Reliable comparisons begin with equal dimensions. If one image is 1200 by 800 pixels and the other is 1000 by 800, placing them into the same overlay without a declared transformation shifts corresponding details and can exaggerate or conceal change. For that reason, the calculator rejects unequal width or height unless `resize_to_match` is enabled. With the flag enabled, the before image becomes the canonical target and the result includes the after image target dimensions plus independent horizontal and vertical scale factors. This policy is intentionally explicit: it tells the renderer exactly what adjustment is expected and gives reviewers enough information to detect non-uniform stretching. The tool does not perform the resize or choose a crop. If preserving aspect ratio matters, prepare matching sources or apply a crop in an image pipeline before requesting the layout. When dimensions already match, the resize object simply reports that no resize is required. This keeps successful results structurally predictable while avoiding optional null fields.
Turn divider output into a working interface
For a slider overlay, provide a divider percentage from zero through one hundred. The calculator converts it to the nearest pixel within the comparison canvas and returns two clips whose widths always add up to the full image width. At zero percent, the before clip has zero width and the after image is fully exposed; at one hundred percent, the reverse is true. The unchanged percentage is also returned for UI state, accessibility values, analytics, or later recalculation after a responsive resize. In side-by-side mode, two full-width panels determine the divider naturally, so it sits at the midpoint of the combined canvas regardless of the slider percentage input. Use the returned orientation and x coordinate to position a line, handle, or keyboard-operable control. A production slider should expose its current value to assistive technology, support arrow-key changes, and label which side is before and which is after. Because this capability returns geometry rather than markup, the same deterministic result can drive a website component, generated social graphic, design-system preview, or mobile application.
What you can do with it
Document a renovation
Lay out aligned room photographs as complete adjacent panels or as an interactive reveal slider.
Present an image edit
Generate exact overlay clips for retouching, restoration, color grading, or background-removal previews.
Standardize comparison components
Give web and mobile renderers the same deterministic canvas, rectangles, resize plan, and divider geometry.
FAQ
What does the API request cost?
Each API request costs $0.002. The browser tool on this page is free to use.
Does this tool modify or upload my images?
No. It receives dimensions only and returns layout coordinates; it does not read, transfer, store, or render image bytes.
What happens when the dimensions differ?
The request returns an invalid-input error unless resize_to_match is true. When enabled, the output describes how to resize the after image to the before image dimensions.
How is the slider divider pixel calculated?
The image width is multiplied by the requested percentage and divided by 100, then rounded to the nearest whole pixel.
Does the divider percentage affect side-by-side mode?
No. Side-by-side mode shows two complete equal-size panels, so the divider is always their boundary at 50 percent of the combined canvas.
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/compare-before-after-layout \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"before_width":1200,"before_height":800,"after_width":1200,"after_height":800}'const res = await fetch("https://api.kit.forhosting.com/image/compare-before-after-layout", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"before_width": 1200,
"before_height": 800,
"after_width": 1200,
"after_height": 800
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/compare-before-after-layout",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"before_width": 1200,
"before_height": 800,
"after_width": 1200,
"after_height": 800
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/compare-before-after-layout", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"before_width":1200,"before_height":800,"after_width":1200,"after_height":800}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"before_width":1200,"before_height":800,"after_width":1200,"after_height":800}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/compare-before-after-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
{
"before_width": 1200,
"before_height": 800,
"after_width": 1200,
"after_height": 800
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.compare_before_after_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. |