```bash cURL
# This reference implementation is local math that makes no API request, so
# there's nothing to show for cURL. See the SDK tabs.
```
```bash CLI
# This reference implementation is local math that makes no API request, so
# there's nothing to show for the CLI. See the SDK tabs.
```
```python Python
import math
def count_image_tokens(width: int, height: int) -> int:
"""Visual tokens consumed by an image: one token per 28x28 pixel patch."""
return math.ceil(width / 28) * math.ceil(height / 28)
def resized_size(
width: int,
height: int,
max_edge: int = 1568,
max_tokens: int = 1568,
) -> tuple[int, int]:
"""The size Claude resizes an image to before padding.
Defaults are for the standard resolution tier. For high-resolution-tier
models, use max_edge=2576 and max_tokens=4784. Returns (width, height).
Images that already fit within the limits are returned unchanged.
"""
def fits(w: int, h: int) -> bool:
return (
math.ceil(w / 28) * 28 <= max_edge
and math.ceil(h / 28) * 28 <= max_edge
and count_image_tokens(w, h) <= max_tokens
)
if fits(width, height):
return (width, height)
if height > width:
resized_h, resized_w = resized_size(height, width, max_edge, max_tokens)
return (resized_w, resized_h)
# Binary search along the long edge for the largest aspect-preserving
# size that fits.
aspect_ratio = width / height
lo, hi = 1, width # lo always fits; hi never fits
while lo + 1 < hi:
mid = (lo + hi) // 2
if fits(mid, max(round(mid / aspect_ratio), 1)):
lo = mid
else:
hi = mid
return (lo, max(round(lo / aspect_ratio), 1))
# The A4 example from "How Claude resizes and pads images":
print(resized_size(1075, 1520)) # (924, 1307)
# To apply the resize, use your image library, for example Pillow:
# image.resize(resized_size(*image.size))
```
```typescript TypeScript
/** Visual tokens consumed by an image: one token per 28x28 pixel patch. */
function countImageTokens(width: number, height: number): number {
return Math.ceil(width / 28) * Math.ceil(height / 28);
}
/**
* Round half to even (banker's rounding), matching Python's round(). The
* live API resolves exact .5 ties toward the even neighbor, so Math.round
* (which rounds halves up) would compute a different size for some images.
*/
function roundTiesToEven(value: number): number {
const floor = Math.floor(value);
if (value - floor !== 0.5) return Math.round(value);
return floor % 2 === 0 ? floor : floor + 1;
}
/**
* The size Claude resizes an image to before padding.
*
* Defaults are for the standard resolution tier. For high-resolution-tier
* models, use maxEdge = 2576 and maxTokens = 4784. Returns [width, height].
* Images that already fit within the limits are returned unchanged.
*/
function resizedSize(
width: number,
height: number,
maxEdge = 1568,
maxTokens = 1568
): [number, number] {
const fits = (w: number, h: number): boolean =>
Math.ceil(w / 28) * 28 <= maxEdge &&
Math.ceil(h / 28) * 28 <= maxEdge &&
countImageTokens(w, h) <= maxTokens;
if (fits(width, height)) return [width, height];
if (height > width) {
const [resizedH, resizedW] = resizedSize(height, width, maxEdge, maxTokens);
return [resizedW, resizedH];
}
// Binary search along the long edge for the largest aspect-preserving
// size that fits.
const aspectRatio = width / height;
let lo = 1; // lo always fits
let hi = width; // hi never fits
while (lo + 1 < hi) {
const mid = Math.floor((lo + hi) / 2);
if (fits(mid, Math.max(roundTiesToEven(mid / aspectRatio), 1))) {
lo = mid;
} else {
hi = mid;
}
}
return [lo, Math.max(roundTiesToEven(lo / aspectRatio), 1)];
}
// The A4 example from "How Claude resizes and pads images":
console.log(resizedSize(1075, 1520)); // [ 924, 1307 ]
// To apply the resize, use your image library, for example sharp:
// await sharp(input).resize(width, height).toBuffer()
```
```csharp C#
// Visual tokens consumed by an image: one token per 28x28 pixel patch.
static int CountImageTokens(int width, int height)
{
return (width + 27) / 28 * ((height + 27) / 28); // ceil(w/28) * ceil(h/28)
}
// The size Claude resizes an image to before padding. Defaults are for the
// standard resolution tier; for high-resolution-tier models, pass
// maxEdge: 2576, maxTokens: 4784. Images that already fit within the limits
// are returned unchanged.
static (int Width, int Height) ResizedSize(
int width, int height, int maxEdge = 1568, int maxTokens = 1568)
{
bool Fits(int w, int h) =>
(w + 27) / 28 * 28 <= maxEdge
&& (h + 27) / 28 * 28 <= maxEdge
&& CountImageTokens(w, h) <= maxTokens;
if (Fits(width, height))
{
return (width, height);
}
if (height > width)
{
(int resizedH, int resizedW) = ResizedSize(height, width, maxEdge, maxTokens);
return (resizedW, resizedH);
}
// Binary search along the long edge for the largest aspect-preserving
// size that fits. The short edge rounds half to even, matching the live
// API at exact .5 ties (MidpointRounding.ToEven, Math.Round's default).
double aspectRatio = (double)width / height;
int lo = 1; // lo always fits
int hi = width; // hi never fits
while (lo + 1 < hi)
{
int mid = (lo + hi) / 2;
if (Fits(mid, ShortEdge(mid)))
{
lo = mid;
}
else
{
hi = mid;
}
}
return (lo, ShortEdge(lo));
int ShortEdge(int longEdge) =>
Math.Max((int)Math.Round(longEdge / aspectRatio, MidpointRounding.ToEven), 1);
}
// The A4 example from "How Claude resizes and pads images":
Console.WriteLine(ResizedSize(1075, 1520)); // (924, 1307)
```
```go Go
// countImageTokens is the visual tokens consumed by an image: one token per
// 28x28 pixel patch.
func countImageTokens(width, height int) int {
return ((width + 27) / 28) * ((height + 27) / 28) // ceil(w/28) * ceil(h/28)
}
// resizedSize is the size Claude resizes an image to before padding, as
// (width, height). Pass maxEdge 1568 and maxTokens 1568 for the standard
// resolution tier, or 2576 and 4784 for the high-resolution tier. Images
// that already fit within the limits are returned unchanged.
// The A4 example from "How Claude resizes and pads images":
// resizedSize(1075, 1520, 1568, 1568) returns (924, 1307).
func resizedSize(width, height, maxEdge, maxTokens int) (int, int) {
fits := func(w, h int) bool {
return ((w+27)/28)*28 <= maxEdge &&
((h+27)/28)*28 <= maxEdge &&
countImageTokens(w, h) <= maxTokens
}
if fits(width, height) {
return width, height
}
if height > width {
resizedH, resizedW := resizedSize(height, width, maxEdge, maxTokens)
return resizedW, resizedH
}
// Binary search along the long edge for the largest aspect-preserving
// size that fits. The short edge rounds half to even (math.RoundToEven),
// matching the live API at exact .5 ties; math.Round would round them up.
aspectRatio := float64(width) / float64(height)
lo, hi := 1, width // lo always fits; hi never fits
for lo+1 < hi {
mid := (lo + hi) / 2
short := max(int(math.RoundToEven(float64(mid)/aspectRatio)), 1)
if fits(mid, short) {
lo = mid
} else {
hi = mid
}
}
return lo, max(int(math.RoundToEven(float64(lo)/aspectRatio)), 1)
}
```
```java Java
/** A resized image size, as returned by resizedSize. */
record Size(int width, int height) {}
/** Visual tokens consumed by an image: one token per 28x28 pixel patch. */
static int countImageTokens(int width, int height) {
return Math.ceilDiv(width, 28) * Math.ceilDiv(height, 28);
}
/**
* The size Claude resizes an image to before padding.
*
* Pass maxEdge 1568 and maxTokens 1568 for the standard resolution tier,
* or 2576 and 4784 for the high-resolution tier. Images that already fit
* within the limits are returned unchanged.
*
*
The A4 example from "How Claude resizes and pads images":
* resizedSize(1075, 1520, 1568, 1568) returns new Size(924, 1307).
*/
static Size resizedSize(int width, int height, int maxEdge, int maxTokens) {
if (fits(width, height, maxEdge, maxTokens)) {
return new Size(width, height);
}
if (height > width) {
Size rotated = resizedSize(height, width, maxEdge, maxTokens);
return new Size(rotated.height(), rotated.width());
}
// Binary search along the long edge for the largest aspect-preserving
// size that fits. The short edge rounds half to even (Math.rint),
// matching the live API at exact .5 ties; Math.round would round them up.
double aspectRatio = (double) width / height;
int lo = 1; // lo always fits
int hi = width; // hi never fits
while (lo + 1 < hi) {
int mid = (lo + hi) / 2;
if (fits(mid, shortEdge(mid, aspectRatio), maxEdge, maxTokens)) {
lo = mid;
} else {
hi = mid;
}
}
return new Size(lo, shortEdge(lo, aspectRatio));
}
private static boolean fits(int width, int height, int maxEdge, int maxTokens) {
return Math.ceilDiv(width, 28) * 28 <= maxEdge
&& Math.ceilDiv(height, 28) * 28 <= maxEdge
&& countImageTokens(width, height) <= maxTokens;
}
private static int shortEdge(int longEdge, double aspectRatio) {
return Math.max((int) Math.rint(longEdge / aspectRatio), 1);
}
```
```php PHP
// Visual tokens consumed by an image: one token per 28x28 pixel patch.
function countImageTokens(int $width, int $height): int
{
return intdiv($width + 27, 28) * intdiv($height + 27, 28);
}
/**
* The size Claude resizes an image to before padding, as [width, height].
*
* Defaults are for the standard resolution tier. For high-resolution-tier
* models, pass maxEdge: 2576, maxTokens: 4784. Images that already fit
* within the limits are returned unchanged.
*/
function resizedSize(int $width, int $height, int $maxEdge = 1568, int $maxTokens = 1568): array
{
$fits = fn (int $w, int $h): bool =>
intdiv($w + 27, 28) * 28 <= $maxEdge
&& intdiv($h + 27, 28) * 28 <= $maxEdge
&& countImageTokens($w, $h) <= $maxTokens;
if ($fits($width, $height)) {
return [$width, $height];
}
if ($height > $width) {
[$resizedH, $resizedW] = resizedSize($height, $width, $maxEdge, $maxTokens);
return [$resizedW, $resizedH];
}
// Binary search along the long edge for the largest aspect-preserving
// size that fits. The short edge rounds half to even
// (PHP_ROUND_HALF_EVEN), matching the live API at exact .5 ties.
$aspectRatio = $width / $height;
$lo = 1; // lo always fits
$hi = $width; // hi never fits
while ($lo + 1 < $hi) {
$mid = intdiv($lo + $hi, 2);
$short = max((int) round($mid / $aspectRatio, 0, PHP_ROUND_HALF_EVEN), 1);
if ($fits($mid, $short)) {
$lo = $mid;
} else {
$hi = $mid;
}
}
return [$lo, max((int) round($lo / $aspectRatio, 0, PHP_ROUND_HALF_EVEN), 1)];
}
// The A4 example from "How Claude resizes and pads images":
[$resizedWidth, $resizedHeight] = resizedSize(1075, 1520);
echo "({$resizedWidth}, {$resizedHeight})\n"; // (924, 1307)
```
```ruby Ruby
# Visual tokens consumed by an image: one token per 28x28 pixel patch.
def count_image_tokens(width, height)
width.ceildiv(28) * height.ceildiv(28)
end
# The size Claude resizes an image to before padding, as [width, height].
#
# Defaults are for the standard resolution tier. For high-resolution-tier
# models, pass max_edge: 2576, max_tokens: 4784. Images that already fit
# within the limits are returned unchanged.
def resized_size(width, height, max_edge = 1568, max_tokens = 1568)
fits = lambda do |w, h|
w.ceildiv(28) * 28 <= max_edge &&
h.ceildiv(28) * 28 <= max_edge &&
count_image_tokens(w, h) <= max_tokens
end
return [width, height] if fits.call(width, height)
if height > width
resized_h, resized_w = resized_size(height, width, max_edge, max_tokens)
return [resized_w, resized_h]
end
# Binary search along the long edge for the largest aspect-preserving
# size that fits. The short edge rounds half to even (round(half: :even)),
# matching the live API at exact .5 ties.
aspect_ratio = width.fdiv(height)
lo = 1 # lo always fits
hi = width # hi never fits
while lo + 1 < hi
mid = (lo + hi) / 2
short = [(mid / aspect_ratio).round(half: :even), 1].max
if fits.call(mid, short)
lo = mid
else
hi = mid
end
end
[lo, [(lo / aspect_ratio).round(half: :even), 1].max]
end
# The A4 example from "How Claude resizes and pads images":
p resized_size(1075, 1520) # => [924, 1307]
```
1. Resize the image to the dimensions returned by the resize helper. If the image already fits within the model's limits, the helper returns its dimensions unchanged and no resize is needed.
2. [Send the resized image](https://platform.claude.com/docs/en/build-with-claude/vision#send-images-to-claude) to the API. Don't pad it yourself. Claude handles padding, and padding doesn't shift the coordinate origin.
3. In your prompt, ask explicitly for pixel coordinates. For example: *"Return the click point for the Submit button as `[x, y]` in pixel coordinates."*
4. Use the returned coordinates directly against the image you sent. If you need normalized coordinates, divide by the dimensions of the image you sent, not by the original image's dimensions and not by the padded dimensions.