Equivalent exposure calculator
Stopping down from f/4 to f/8 at 1/125 and ISO 100 means a shutter of 0.032 s to keep the same light. Change one setting, pick another to compensate and get the exact value. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Base f-number
- 4
- Shutter
- 0.008
- Base ISO sensitivity
- 100
- New aperture
- 8
- Calculate
- Shutter
- Changed
- aperture
- Changed value
- 8
- Solved value
- 0.032
Photographers balance three linked settings—aperture f-number, shutter speed in seconds, and ISO sensitivity—so the sensor or film receives the same total light when one corner of the triangle moves. Opening from f slash four to f slash eight cuts light by two stops; holding brightness constant means lengthening the shutter or raising ISO by the same two stops. This equivalent exposure calculator accepts a base triangle, exactly one changed setting, and the corner you want to solve for, then returns the unique positive compensating value from the closed-form rule that relative exposure is proportional to ISO times shutter over aperture squared.
How equivalent exposure works on the triangle
Start from a base exposure defined by three strictly positive numbers: the f-number N of the lens (larger N means a smaller opening and less light), the shutter time t in seconds (longer time means more light), and the ISO sensitivity S (higher S means more gain for the same photons). A convenient relative exposure measure is E equals S times t divided by N squared.
Any two exposures with the same E deliver the same total light energy to the image plane under the usual reciprocity assumptions, ignoring flash duration, ND filters, and reciprocity failure at extreme times. When a photographer changes exactly one corner—for example moving from N equals four to N equals eight—the light ratio from aperture alone is the square of the f-number ratio, here one quarter, which is two full stops less light.
To restore equal exposure you must multiply shutter time by four, multiply ISO by four, or combine partial moves on both remaining corners; this calculator always holds the untouched corner fixed and solves the single free variable so E matches the base. Stop language is available too: aperture stop change is minus two times log base two of N final over N base, shutter stop change is log base two of t final over t base, and ISO stop change is log base two of S final over S base.
Their algebraic sum is zero when compensation is exact, which is a useful sanity check next to the raw solved value. Zero, negative, NaN, and Infinity settings are rejected early because they are not physical triangle corners and would break the closed-form division and square root.
Where equivalent exposure calculators show up in real work
Photography and cinematography courses constantly assign triangle drills: freeze action with a faster shutter then recover brightness with aperture or ISO; deepen depth of field by stopping down then lengthen time under a tripod; match a sunny-sixteen daylight set to an indoor tungsten set by trading ISO. A single trusted oracle that returns the compensating number plus stop deltas speeds grading and demo setup.
Location still photographers building look books need quick swaps when a client wants shallower depth of field without changing ambient brightness, and assistants want a phone-friendly calculator that does not silently accept zero ISO. If you later need only the geometric f-number from focal length and pupil diameter, depth-of-field tables, flash guide numbers, or color-temperature conversion, treat those as separate search intents and landings rather than overloading this equivalent exposure calculator page.
What you can do with it
On-set aperture and shutter trades
Stop down two f-stops for deeper focus and instantly get the longer shutter (or higher ISO) that keeps the same brightness under fixed light.
Homework and exam exposure tables
Generate answer keys for triangle problems with solved values, stop deltas, and EV so teachers and auto-graders share one ground truth.
FAQ
What is equivalent exposure?
Two aperture–shutter–ISO combinations are equivalent when they deliver the same total light. This tool uses E ∝ (ISO · shutter) / aperture² and solves so E matches the base.
What happens if a setting is zero or negative?
Exposure triangle settings must be finite and strictly positive; zero would break division or the square root.
Can I enter shutter as a fraction like 1/125?
Yes. Shutter fields accept decimal seconds (0.008) or fraction strings such as "1/125".
What does it cost?
The browser tool is free and runs locally.
What shutter speed keeps the same exposure if I go from f/4 to f/8?
Going from 1/125 at f/4 to f/8 at ISO 100 needs 0.032 s. Closing the aperture two stops cuts the light to a quarter, so the shutter has to stay open 4 times longer.
Related tools
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/hobby/equivalent-exposure \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"aperture":4,"shutter":0.008,"iso":100,"solve_for":"shutter"}'const res = await fetch("https://api.kit.forhosting.com/hobby/equivalent-exposure", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"aperture": 4,
"shutter": 0.008,
"iso": 100,
"solve_for": "shutter"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/hobby/equivalent-exposure",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"aperture": 4,
"shutter": 0.008,
"iso": 100,
"solve_for": "shutter"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/hobby/equivalent-exposure", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"aperture":4,"shutter":0.008,"iso":100,"solve_for":"shutter"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"aperture":4,"shutter":0.008,"iso":100,"solve_for":"shutter"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/hobby/equivalent-exposure", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"aperture": 4,
"shutter": 0.008,
"iso": 100,
"solve_for": "shutter"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "hobby.equivalent_exposure",
"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.
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. |
Technical notes
Non-positive settings, missing base fields, and contradictory solve_for choices fail with a clear invalid_input error instead of inventing Infinity or NaN.
What you send and what you get back
Send a base aperture as a positive f-number, a base shutter as positive seconds (decimal or a fraction string such as one slash one two five), and a base ISO as a positive sensitivity. A stops object reports per-corner stop deltas, a net sum near zero, and an EV residual so clients can assert equality in tests. Classic checks include base f slash four at one one two fifth of a second and ISO one hundred with new aperture eight solving for shutter near zero point zero three two seconds, or raising ISO from two hundred to eight hundred while solving for a quarter shutter time. Wire the free browser form for on-set mental math checks, then call the identical contract from scripts when you need bulk generation of exposure tables or exam answer keys. Then set exactly one of new_aperture, new_shutter, or new_iso to the value the photographer actually chose, and set solve_for to aperture, shutter, or ISO naming a different corner to compute. All three base fields and solve_for are required; providing zero or two-or-more changed fields fails with invalid_input. Aliases include f_number and f_stop for aperture, shutter_speed and exposure_time for shutter, sensitivity and asa for ISO, and compensate or find for solve_for. Missing fields, non-numeric strings, NaN, Infinity, non-positive settings, and a solve_for that matches the changed corner fail without charge. On success the response echoes a base block with cleaned numbers, f-stop and shutter labels, relative exposure, and EV; names the changed corner and its value; returns solved_value for the compensating corner; and provides a compensated block with the full final triangle, labels, relative exposure, and EV. Pricing for successful API calls is the published base of $0.002 per item; validation failures do not consume prepaid balance.
Where equivalent exposure calculators show up in real work
Firmware authors, light-meter apps, and camera-simulation games encode the same E proportional rule when previewing what happens if the user turns the aperture dial; having a pure parse endpoint avoids re-implementing fraction shutters and EV labels in every client. Because this capability is a pure parse engine, API pricing is the published base of $0.002 per successful item and failed validation does not consume balance.
Integration use cases
Camera app and light-meter fixtures
Bulk-produce equivalent triangles for UI previews and regression tests when the user changes one dial and another compensates.
Technical questions
Which fields are required?
Base aperture, shutter (seconds), and ISO, plus exactly one of new_aperture, new_shutter, or new_iso, and solve_for naming a different corner (aperture, shutter, or iso).