Back to posts
AINews

Crop the screenshot before you send it: a 4K capture reaches Claude as 1456×819

Vision models bill by patch and silently downscale anything over budget, so a full-screen capture arrives with 4.5-pixel text and a full-price token bill. The patch arithmetic, the limit that resizes images already under the size cap, and the flag that turns the silent resize into a 400.

You screenshot a dashboard, hand it to your agent, and ask for the figure in the third panel. It answers with a number that is close to right and is not right. The reflex is to blame the model for making things up. The likelier explanation is duller: the model read exactly what it was given, and what it was given had text about four pixels tall.

Vision pricing is not charged per image. It is charged per patch, and every provider caps how many patches one image is allowed to occupy. Go over the cap and the image is scaled down before the model ever looks at it. Nothing in the response tells you this happened.

The arithmetic

Claude divides an image into 28×28 pixel blocks and charges one visual token per block, so an image costs ⌈width / 28⌉ × ⌈height / 28⌉ tokens. You can check any figure in this post with two lines:

import math

def image_tokens(width: int, height: int) -> int:
    return math.ceil(width / 28) * math.ceil(height / 28)

Each model sits in one of two resolution tiers, and the tier sets both a long-edge cap and a visual-token budget:

TierModelsMax long edgeMax visual tokens
High-resolutionClaude 4.7 and later2576 px4784
StandardAll other models1568 px1568

A 3840×2160 capture would cost 10,764 tokens at full size. Neither tier will accept that. On the standard tier it arrives as 1456×819 and bills 1560 tokens; on the high-resolution tier it arrives as 2576×1449 and bills 4784. The standard-tier version has been scaled to 37.9 percent of the original, which turns 12-pixel UI text into 4.5-pixel text. You paid 1560 tokens for an image whose numbers are no longer legible.

The limit that catches people out

There are two limits, and the second one does most of the damage because it fires on images that look safely small.

An A4 page scanned at 130 DPI is 1075×1520 pixels. Both sides are comfortably under the 1568-pixel edge cap, so the instinct is that nothing happens to it. It costs 39 × 55 = 2145 visual tokens, which is over the standard tier's 1568-token budget, so it is resized to 924×1307 anyway. Anthropic's coordinate guide calls this the most common cause of misaligned bounding boxes, and it is the same mechanism that quietly degrades OCR accuracy on document pipelines.

For photos and screenshots, the token budget is almost always the binding constraint. The edge cap only takes over on elongated images: panoramas, tall phone screenshots, long receipts.

What a crop buys

Compare sending the whole screen against sending only the panel you asked about, on a standard-tier model:

What you sendDelivered to the modelVisual tokens
Full 3840×2160 screen1456×819, scaled to 37.9%1560
1000×600 crop of one panel1000×600, untouched792
1200×700 crop of one panel1200×700, untouched1075

The crop costs roughly half and every pixel of the region you care about survives at native resolution. This inverts the usual cost/quality trade: sending less is both cheaper and more accurate, because the thing you were paying for in the full capture was mostly the parts of the screen you did not ask about, plus the scale factor that destroyed the parts you did.

Three targeted crops usually still beat one full screen. Even at 792 tokens each, two crops land at 1584 tokens against the full screen's 1560, with all three regions legible instead of none.

Anthropic's own worked example puts real money on it. At Haiku 4.5's rate of $1 per million input tokens, a 1000×1000 image runs about $1.30 per thousand images. At Opus 5's $5 per million on the high-resolution tier, the same image is about $6.48 per thousand and a 4K capture about $23.92 per thousand. A browser agent taking a screenshot per step reaches those thousands quickly.

Turn the silent resize into a 400

Pre-resizing in your own pipeline only holds while your pipeline keeps producing the right sizes. A new capture source or a model swap across tiers reintroduces server-side resizing without a single line of your code changing. Set transformations on the image block and the resize becomes a rejection instead:

{
  "type": "image",
  "source": { "type": "base64", "media_type": "image/png", "data": "..." },
  "transformations": { "oversized_image": "error" }
}

A marked image that would be resized comes back as a 400 that names both the dimensions you sent and the target you should have sent:

messages.0.content.0: image dimensions 1920x1080 exceed the maximum image size
of a model named on this request and would be downsized to 1456x819; scale the
image to at most 1456x819 or set the image's oversized_image setting to "downsize"

The setting is per image, so one request can mark the screenshot whose pixel coordinates you intend to click on while leaving a decorative logo on the default "downsize". The token-counting endpoint honors the same field, which means you can test whether an embedded image survives intact before you pay for inference on it.

Two paths where the rules differ

Screenshots returned to the computer use and browser use toolsets are not downscaled. An oversized image inside a tool_result is rejected with a validation error instead. If your agent loop hands back raw screen captures from a 4K display, resize them in your application first, then scale the coordinates the model returns back to screen space. On a HiDPI display, divide by the display scale factor as well.

Requests carrying more than 20 image blocks get a stricter per-image dimension limit applied to every image in the request. The count includes images from earlier turns that you resend and images nested inside tool_result content, which is exactly what an agent loop accumulates. A long computer-use session can cross the threshold mid-run and start failing on images that were fine ten turns earlier. Keep each side at or below 2000 pixels, or keep the request to 20 or fewer image blocks.

While you are in that loop: base64 image data is re-sent in full on every turn, because each request carries the whole conversation. Uploading once through the Files API and referencing the returned file_id keeps the payload flat as screenshots pile up.

If you are not on Claude

The mechanism generalizes; the constants do not. OpenAI's patch-based models cover the image in 32×32 patches, ceil(width / 32) × ceil(height / 32), against a per-model patch budget, and resize when the count exceeds it. The detail parameter controls the behavior directly: low swaps in a 512×512 version regardless of what you sent, original skips the resize entirely, and auto resolves differently across model generations. Whichever provider you are on, the question worth answering before you optimize anything else is the same one: what dimensions does the model receive, and is the text you need still readable at that size?

The check, in order

  1. Look up which tier your model is on. The same capture can cost three times as much on the high-resolution tier for fidelity you may not need.
  2. Run the patch formula on a typical capture from your pipeline. If it exceeds the tier budget, your images are being resized right now.
  3. Crop to the region the prompt asks about instead of capturing the full screen. Send several crops rather than one panorama.
  4. Set "oversized_image": "error" on any image whose pixel dimensions are load-bearing, so drift surfaces as a failed request rather than a wrong answer.
  5. In agent loops, resize tool_result screenshots yourself, watch the 20-image threshold, and move repeated images to the Files API.

None of this makes the model better at reading. It stops you from paying full price for an image the model was never able to read in the first place.

Related: what a token is and why output costs more than input, cutting Claude Code's fixed token overhead, and checking your real cost per million tokens.

Get the next post when it ships

One email on Sunday with the new post and a short list of what shipped that week — new guides, tool updates, and a couple of links worth reading.