Engineering 24 min read

Send Your Notes to the AI as an Image and It Guesses the Numbers

MMNMNOTE
aitokensvision modelsscreenshotscontext compressionaccuracymarkdown

An AI model bills an image by its size, not by how much text it holds. So a dense page of notes costs far fewer tokens as a picture — 64% to 81% fewer in one independent test. The model still gets the gist. The exact values — IDs, amounts, dates — come back as plausible guesses, with no warning.

The trick is no longer a curiosity. An open-source proxy, pxpipe, renders an AI coding agent's bulky context as dense PNG pages to cut the input bill. Its README is unusually candid about the cost: "It is lossy."1 On 2026-10-21 an independent tester, TokenSave, ran 144 calls against four Claude models and published the data with a DOI.2 As plain text, every model answered every question correctly. Through pxpipe, the best model got 44 of 60 planted numbers right.

What follows works the provider's cost formula for one page of notes and explains why a picture of a number is not the number. Then come the measurements — including peer-reviewed work that found no loss at moderate density — and a two-minute test you can run on your own notes. Every model name and percentage below is a dated measurement, not a permanent fact.


What does a picture of your notes cost?

On Claude, an image costs one visual token per 28×28-pixel patch, whatever the patch contains. A phone-width screenshot of one note page, 800×1000 pixels, costs 1,044 visual tokens — the same for a single line of text or a packed page. Text is billed per token of content; a picture is billed per square of area.

Anthropic's vision documentation states the rule in one line: "Each patch is a 28×28-pixel block of the image, referred to as a visual token. An image, therefore, costs ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens."3 The same page gives a worked table — a 1000×1000 image is 1,296 tokens — which makes the formula easy to check.

import math

def visual_tokens(width, height):
    """Claude's documented image cost: one visual token per 28x28-pixel patch."""
    return math.ceil(width / 28) * math.ceil(height / 28)

# Check against the worked-example table in the vision docs
assert visual_tokens(200, 200) == 64
assert visual_tokens(1000, 1000) == 1296
assert visual_tokens(1092, 1092) == 1521

The cost has a ceiling. Each model tier caps the long edge and the visual-token count: 1,568 px and 1,568 tokens on the standard tier. Claude 4.7 and later models use the high-resolution tier — 2,576 px and 4,784 tokens.3 A larger image is downscaled to fit, which caps the price and shrinks the letters.

Other vendors work the same way. OpenAI's vision guide says "Some models tokenize images by covering them with 32px x 32px patches," with patch_count = ceil(width/32)×ceil(height/32); other OpenAI models use tiles.4 Google's Gemini documentation is tile-based: "Images ≤384 pixels in both dimensions count as 258 tokens. Larger images are tiled into 768x768 pixel tiles, each counting as 258 tokens."5 Every vendor bills a picture by its area.

When a screenshot costs more than the text

The image price is fixed by area, so the saving depends entirely on how much text you pack into each patch. Dense content wins. Sparse prose loses — and a short note loses badly.

pxpipe's README gives the two ratios that matter. Dense content "packs ~3.1 chars per image-token vs ~1 char per text-token on real Claude Code traffic," and the tool "loses money on sparse prose (~3.5 chars/token)."61 Run those through the formula for the same 800×1000 page:

w, h = 800, 1000              # a phone-width screenshot of one note page
cost = visual_tokens(w, h)    # 1044 visual tokens, one line or a full page

dense_text = cost * 1.0       # ~1 char per text token (code, IDs, logs)
prose_text = cost * 3.5       # ~3.5 chars per text token (ordinary prose)
packed     = cost * 3.1       # ~3.1 chars per image token at pxpipe's density

print(cost, round(dense_text), round(prose_text), round(packed))
# 1044 1044 3654 3236

Read the output as a rough break-even — our arithmetic over pxpipe's published ratios, not a measurement. The screenshot beats pasting only if it holds more than about 1,000 characters of dense material or about 3,650 characters of ordinary prose.

The last number explains pxpipe's own caution. At its packing density the page holds about 3,240 characters — below the prose break-even — and the README notes that "sparse prose stays text."1

By the same ratio, a 300-character note pasted as prose is roughly 86 tokens. As an 800×1000 screenshot it is 1,044 — about twelve times more.


Why doesn't a picture of text hold the same text?

The naive assumption is that an image of text is the text, read back by built-in OCR. It is not. A vision model turns the image into continuous patch vectors, never into characters, and when the pixels underdetermine a glyph, the model's language habits supply something plausible. Nothing flags the substitution.

pxpipe's author puts the mechanism plainly in the README's FAQ: "Because model vision is not OCR: the image becomes patch embeddings, never discrete characters, so there is no per-glyph confidence to fail loudly on. When pixels underdetermine a glyph, the language prior fills the gap with something plausible."7

Sean Goedecke, writing on his blog, reached the same split from the other side: "The first explanation is that text tokens are discrete while image tokens are continuous."8 A text token is an exact symbol. A patch vector is a description of what some pixels looked like.

That language prior is measurable. In OCRBench, a peer-reviewed benchmark of large multimodal models, scrambling the letters inside each word made accuracy fall sharply: "the accuracy of LMMs on the NST dataset decreased by an average of 57.0% compared to the ST dataset, while the SOTA method for scene text recognition only drops by around 4.6%."9 A dedicated text reader barely noticed. The general-purpose models did not.

The authors explain why: the models "heavily rely on semantic understanding to recognize words, often favoring common words over random letter sequences."9 Their sharpest example is a date. "Even when explicitly requested to answer using the text found in the image, Gemini consistently interprets "02/02/2018" as "2 February 2018"."9

Those models date from 2023–24. pxpipe's 2026 README describes the same mechanism.

An invoice number, a commit hash, an account ID — these are strings with no meaning to lean on. They are exactly what a language prior cannot guess from context.


How the two routes reach the model

Text and images arrive by different roads. Text is cut into discrete tokens that carry the characters themselves, so copying a value back is a lookup. An image is cut into patches that become continuous vectors, so copying a value back is a reconstruction — and an unresolved glyph is filled by inference.

Text route
  "INV-94392"  ─►  tokenizer  ─►  discrete tokens
  The model receives the characters themselves.

Image route
  picture of "INV-94392"
    ─►  cut into fixed patches (Claude: 28×28 px)
    ─►  each patch becomes a continuous vector
    ─►  the model infers which characters it saw
    ─►  a glyph it cannot resolve is filled in by
        the language prior: plausible, unflagged

Figure: the text route hands the model exact characters; the image route hands it a description of pixels, and any glyph the pixels underdetermine is filled in by the model's sense of what usually comes next.

The difference explains both halves of the result. Meaning survives a reconstruction well, because a sentence with one blurred letter is still the same sentence.

A number does not. "94392" with one blurred digit is a different number.

This is also why an earlier piece here, on alt text for screenshots, stopped where it did. A text-only search tool cannot see an image at all. A model that can see it gets the gist and loses the digits.


What two measurements found

Both measurements agree. Rendering context as images cut Claude's input tokens by 64% to 81% in TokenSave's runs, measured 2026-10-21 with pxpipe 0.15.0. As text, every model answered every item correctly. As images alone, the best model returned 29 of 60 planted numbers — and the wrong answers looked right.

TokenSave's method is simple. Six documents of 10,600 to 23,200 characters — English, Korean and Japanese prose, source code, JSON and a server log — each received five planted lines carrying an ID and a number. Each document went to four Claude models as text, through pxpipe as images plus pxpipe's text list of identifiers, and as images only. Two runs each.2

Input tokens per document (Opus 5.5 profile, mean of 2 runs, measured 2026-10-21)2

DocumentAs textAs pxpipe imagesChange
English prose5,8702,100−64%
Korean prose9,4832,142−77%
Code7,5861,906−75%
Server log13,0532,935−78%

Fable 5.1's denser profile cut a few points more, up to −81% on the log. TokenSave's own line: "the more tokens a language costs as text, the more an image saves."2 That rhymes with an earlier piece on why non-English notes cost more tokens.

Planted values read back correctly (out of 60, both runs; as text, all correct)2

ModelIDs, pxpipeIDs, images onlyNumbers, pxpipeNumbers, images only
Haiku 5.521/603/6022/6010/60
Sonnet 5.549/6012/6040/6020/60
Opus 5.558/6014/6044/6029/60
Fable 5.141/603/6028/606/60

The tester notes that pxpipe does not enable Haiku by default.2

The "pxpipe" columns include a text list of identifiers the proxy sends beside the images. The planted IDs mostly came back through that list, not the picture. IDs that were not on the list — most of the request IDs in the 230-line log — "were read 0 of 80 times across all four models."2

pxpipe's own evaluations point the same way. Under the README heading "The honest part": "It is lossy. Exact 12-char hex strings in dense imaged content: 13/15 on Fable 5 and 0/15 on Sol — misses are silent confabulations, not errors. Byte-exact values (IDs, hashes, secrets) must stay text; recent turns do."1 Elsewhere it reports that "blind reads top out at 63% on dense identifiers."7

The failures do not announce themselves

Every model in TokenSave's test was told to answer null when unsure. Some did not. From the write-up:

Despite "null if unsure", models sometimes returned a plausible wrong value: 94392 read as 9392, a number that is not in the document10

pxpipe's README records the same failure outside a benchmark: "the model recalled a person's name from imaged chat history and got it confidently wrong. No error, just a plausible wrong name."7

A wrong value with no error is the worst kind. It passes review.


Where the line falls: density, not images

Images do not always lose numbers. A peer-reviewed study found that text rendered as an image held exact-number retrieval at about half the tokens. The failure is a threshold: past a certain density of text per visual token, accuracy "falls rapidly." The aggressive savings that tools advertise sit above that line.

The study is Li, Lan and Zhou's Text or Pixels?, published in Findings of EMNLP 2025. Its abstract reports that "this text-as-image method yields substantial token savings without degrading task performance" on two benchmarks, long-context retrieval and document summarization.11 The retrieval task hides a single target number in a long passage and asks for it back exactly.12 That is close to the planted-number test, and at that density it passed.

The same paper names the limit. "Both models degrade as text density increases, though Qwen's larger decoder sustains higher ratios before a sharper drop."12 And: "Beyond these limits, accuracy falls rapidly, revealing the maximum achievable compression without loss."12 Across models and image sizes, the safe point sat at a compression ratio around 2 — about half the tokens.12

A model trained for this job does better, but not perfectly. DeepSeek-OCR, a preprint rather than a peer-reviewed paper, reports that "when the number of text tokens is within 10 times that of vision tokens (i.e., a compression ratio < 10x), the model can achieve decoding (OCR) precision of 97%. Even at a compression ratio of 20x, the OCR accuracy still remains at about 60%."13 Ninety-seven percent is excellent for prose. For a 12-character ID, it is not a guarantee.

Text tokens per image token, and what happened (ratios are our arithmetic from each source's figures)

SettingRatioExact values
Text or Pixels?, single-number retrieval (GPT-4.1-mini, Qwen2.5-VL-72B)~2×Held within 3 points of the text baseline12
TokenSave, six documents (Opus 5.5 profile)2.8–4.5×Opus 5.5, images only: 29/60 planted numbers2
TokenSave, six documents (Fable profile)3.1–5.3×Fable 5.1, images only: 6/60 planted numbers2
pxpipe, dense imaged content (README example: ~9×)~9×Dense hex strings: 13/15 on Fable 5, 0/15 on Sol61
DeepSeek-OCR, model trained for the task<10× / 20×97% / ~60% decoding precision13

This is not a controlled comparison — the models, tasks and renderers all differ. It still shows the shape. The ratio that holds exact values is about two. The ratios that make the trick worth running are roughly three to nine.

pxpipe's README says as much in five words: "exact recall is limited by pixels per glyph."1


The trade-offs on the rest of the bill

The input line is not the whole bill. One test on OpenAI models found image inputs raised output tokens on all but one. Short notes cost more as images. Downscaling blurs text. And the vendor's own guidance rules out unsupervised precision work. The saving is real for dense context and narrow everywhere else.

Output can grow. PageWatch tested OpenAI models in October 2025 and found the input saving real: "With gpt-5 in particular, we get over a 40% reduction in prompt tokens." Then the catch: "All models apart from gpt-5-chat use significantly more completion tokens with the image inputs."14 It is one small, dated test on another vendor. Its verdict still deserves a hearing: "TLDR: Yes, but only under specific conditions, and it is probably not worth the trade-offs."14

Sparse text loses money. pxpipe "Wins on token-dense content (~1 char/token)" and loses on prose, which is why it puts each kind of input behind a profitability gate.1 A screenshot of a short note is the losing case — the twelvefold cost above.

Downscaling blurs. Anthropic's image-quality guidance warns that "heavy JPEG compression can make text difficult to read," and that a resized image "might, for example, make text less legible."15 Every cost cap is also a legibility cap.

Precision needs a person. The vision documentation ends its limitations list with a direct instruction: "Do not use Claude for tasks requiring perfect precision or sensitive image analysis without human oversight."16

The gist, on the other hand, holds up. pxpipe's own quality table for Opus 5.5, one of the models it enables by default, shows 100/100 on arithmetic and 94/98 on gist questions through images — and 3/15 on dense hex strings.7 Understanding survives. Copying does not.

An earlier piece covered a separate risk: the model adding your numbers up wrong. The image route adds a different one — reading them wrong before any arithmetic starts.

For a reader who screenshots financial or account notes into a chat, one line is enough.

Check every number the model returns against the source before acting on it.


A rule for notes, and a two-minute test

Send an image when the model needs to understand; send text when it needs to copy. A long essay to summarize, an old thread for background, a chart to describe — images are fine. An invoice number, an amount, a date, a version string, a line reference — paste them as text, every time.

TokenSave states the rule in one sentence: "Use image context for what the model needs to understand, not for what it needs to copy."10 Its dataset page adds the list: "Ids, hashes, prices and line numbers should stay text."2

Notes are the hard case for this rule. Send your notes to the AI as an image and the part most likely to be guessed is the part you kept the note for — the confirmation code, the account number, the meter reading, the date the contract renews.

The cheapest way to know where your own setup stands is to test it. The script below plants five exact values in a long note and scores what comes back. Send test-note.md once as pasted text and once as a screenshot, ask the printed question each time, and save each answer as JSON.

# plant5.py: plant five exact values in a note, then score what the AI copies back.
import json, random, sys

def plant(seed):
    rng = random.Random(seed)
    key = {
        "invoice": f"INV-{rng.randint(10000, 99999)}",
        "amount":  f"{rng.randint(1000, 9999)}.{rng.randint(10, 99)}",
        "hash":    "".join(rng.choices("0123456789abcdef", k=12)),
        "date":    f"2026-{rng.randint(1, 12):02d}-{rng.randint(1, 28):02d}",
        "version": f"v{rng.randint(1, 9)}.{rng.randint(0, 40)}.{rng.randint(0, 99)}",
    }
    filler = "Notes from the weekly review. Nothing in this line matters. " * 6
    lines = [filler] * 40
    for i, (name, value) in enumerate(key.items()):
        lines.insert(8 * i + 4, f"The {name} for this project is {value}.")
    open("test-note.md", "w").write("\n\n".join(lines))
    json.dump(key, open("key.json", "w"), indent=2)
    print("Ask: what are the invoice, amount, hash, date and version? Answer null if unsure.")

def score(answers_path):
    key = json.load(open("key.json"))
    got = json.load(open(answers_path))
    for name, want in key.items():
        ans = got.get(name)
        verdict = "ok" if ans == want else ("null" if ans is None else "WRONG")
        print(f"{name:8} want {want:16} got {str(ans):16} {verdict}")

if __name__ == "__main__":
    plant(int(sys.argv[2])) if sys.argv[1] == "plant" else score(sys.argv[2])

Run python3 plant5.py plant 7, then python3 plant5.py score answers-image.json for each answer file. The comparison is exact on purpose: "3471.6" for "3471.60" counts as wrong, because a copied value either matches or it does not.

Read the result by verdict. A null is honest. A WRONG is the failure this piece is about — the plausible substitute.

For real notes, the same check applies to any value a model hands back: make it quote the note, then search the text for that exact string.


Frequently Asked Questions

These answers condense the measurements above. Each figure carries its date, because model names and percentages in this area change from month to month. The mechanism — pixels are billed, characters are reconstructed — does not change, and it is the part worth remembering when the next model ships.

Does sending text as an image save tokens?

For dense text, yes. Claude bills an image per 28×28-pixel patch, so a packed page costs far less than its text. TokenSave measured 64% to 81% fewer input tokens on 2026-10-21. For sparse prose or a short note, no — a screenshot can cost many times more than pasting the same words.32

How are image tokens counted on Claude?

Claude cuts an image into 28×28-pixel patches and charges one visual token per patch: ⌈width/28⌉ × ⌈height/28⌉. A 1000×1000 image costs 1,296 tokens. Larger images are downscaled first. The limits are 1,568 px and 1,568 tokens on the standard tier, and 2,576 px and 4,784 tokens on the high-resolution tier.3

How accurate is pxpipe at reading exact values?

By its own README, it is lossy: dense 12-character hex strings came back 13 of 15 times on Fable 5 and 0 of 15 on Sol. In TokenSave's test of version 0.15.0, IDs that pxpipe did not also send as text were read back 0 of 80 times. In pxpipe's own evaluations, gist and arithmetic held up much better.12

Can AI read numbers from a screenshot accurately?

Usually the gist, not reliably the digits. Through images alone, Opus 5.5 returned 29 of 60 planted numbers correctly in TokenSave's test, and one wrong answer dropped a digit from 94392. At low density, peer-reviewed work found exact-number retrieval held. Verify any number before acting on it.21012

Should I screenshot my notes or paste the text into ChatGPT?

Paste anything you need copied back exactly — IDs, amounts, dates, version strings. A screenshot is fine for describing or summarizing. OpenAI bills images by area too. One October 2025 test found image inputs raised output tokens on all but one OpenAI model it tried, so the total bill may not fall.414

Is a vision model reading an image the same as OCR?

No. An OCR engine outputs characters, usually with a confidence score for each. A vision model turns the image into continuous patch embeddings, so there is no per-character confidence, and an unclear glyph is filled in by the model's language habits. OCRBench found models favour common words over random letter strings.79

Does a bigger, sharper image fix it?

It helps. Text or Pixels? found that larger visual budgets let models hold more text before accuracy dropped, at a steady ratio of about two text tokens per visual token. pxpipe's README puts it as "exact recall is limited by pixels per glyph." More pixels per character, though, means less saving.112


This piece builds on TokenSave's open dataset and on pxpipe's unusually candid README, which published its own failure rates beside its savings.

A picture of a number is a description of a number. Keep the number itself in text.


MNMNOTE keeps notes as plain Markdown text on your own device, so the exact values in them can always reach a model as text, character for character. mnmnote.com


References


Footnotes

  1. teamchong, pxpipe README, section "The honest part" and research status, GitHub, commit 0f16bdb, 2026-10-18. Accessed 2026-10-23. https://github.com/teamchong/pxpipe/blob/0f16bdb3783ea01b3a9f773f49b42fe36a27f2e6/README.md ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9

  2. TokenSave, "Text as images to cut AI tokens: an independent check of pxpipe on Claude" [Data set], CC BY 4.0, DOI 10.5281/zenodo.23525350. Measured 2026-10-21 with pxpipe 0.15.0. Accessed 2026-10-23. https://tokensave.app/data/text-as-image-token-cost ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13

  3. Anthropic, "Vision," Claude Platform documentation, section "Resolution and token cost." Accessed 2026-10-23. https://platform.claude.com/docs/en/build-with-claude/vision ↩ ↩2 ↩3 ↩4

  4. OpenAI, "Images and vision," API guide, section "Calculating costs." Accessed 2026-10-23. https://platform.openai.com/docs/guides/images-vision ↩ ↩2

  5. Google, "Understand and count tokens," Gemini API documentation, last updated 2026-10-13. Accessed 2026-10-23. https://ai.google.dev/gemini-api/docs/tokens ↩

  6. teamchong, pxpipe README, introduction and rendered-page example, GitHub, commit 0f16bdb, 2026-10-18. Accessed 2026-10-23. https://github.com/teamchong/pxpipe/blob/0f16bdb3783ea01b3a9f773f49b42fe36a27f2e6/README.md ↩ ↩2

  7. teamchong, pxpipe README, FAQ and "Model quality" table, GitHub, commit 0f16bdb, 2026-10-18. Accessed 2026-10-23. https://github.com/teamchong/pxpipe/blob/0f16bdb3783ea01b3a9f773f49b42fe36a27f2e6/README.md ↩ ↩2 ↩3 ↩4 ↩5

  8. Goedecke, S., "Should LLMs just treat text content as an image?," seangoedecke.com, 2025-10-21. Accessed 2026-10-23. https://www.seangoedecke.com/text-tokens-as-image-tokens ↩

  9. Liu, Y. et al., "OCRBench: On the Hidden Mystery of OCR in Large Multimodal Models," Science China Information Sciences 67(12):220102, 2024, DOI 10.1007/s11432-024-4235-6. Quoted from arXiv v6, 2024-08-26. Accessed 2026-10-23. https://arxiv.org/html/2305.07895v6 ↩ ↩2 ↩3 ↩4

  10. TokenSave, "Sending text as images cut my Claude tokens by up to 81%. It also started inventing numbers.," dev.to, 2026-10-21. Accessed 2026-10-23. https://dev.to/jaehyun_cho_0dff271e0d2e5/sending-text-as-images-cut-my-claude-tokens-by-up-to-81-it-also-started-inventing-numbers-57ol ↩ ↩2 ↩3

  11. Li, Y., Lan, Z. & Zhou, J., "Text or Pixels? Evaluating Efficiency and Understanding of LLMs with Visual Text Inputs," Findings of EMNLP 2025, pp. 10564–10578, DOI 10.18653/v1/2025.findings-emnlp.558. Accessed 2026-10-23. https://aclanthology.org/2025.findings-emnlp.558/ ↩

  12. Li, Y., Lan, Z. & Zhou, J., "Text or Pixels? It Takes Half: On the Token Efficiency of Visual Text Inputs in Multimodal LLMs," arXiv 2510.18279v2, 2025-10-22. Accessed 2026-10-23. https://arxiv.org/html/2510.18279 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7

  13. Wei, H., Sun, Y. & Li, Y., "DeepSeek-OCR: Contexts Optical Compression," arXiv 2510.18234 (preprint), 2025-10-21. Accessed 2026-10-23. https://arxiv.org/abs/2510.18234 ↩ ↩2

  14. PageWatch, "Can you save on LLM tokens using images instead of text?," 2025-10-27. Accessed 2026-10-23. https://pagewatch.ai/blog/post/llm-text-as-image-tokens/ ↩ ↩2 ↩3

  15. Anthropic, "Vision," Claude Platform documentation, section "Image quality guidance." Accessed 2026-10-23. https://platform.claude.com/docs/en/build-with-claude/vision ↩

  16. Anthropic, "Vision," Claude Platform documentation, section "Limitations." Accessed 2026-10-23. https://platform.claude.com/docs/en/build-with-claude/vision ↩