◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-07-11Advanced

Is This New Wallpaper Too Close to One We Already Ship? Near-Duplicate Detection with a Perceptual-Hash Pre-Filter and Claude Vision

A two-stage pipeline that catches the near-duplicates a SHA256 hash misses — recolored, lightly cropped, re-encoded — by pre-filtering with a perceptual hash and adjudicating only the close pairs with Claude Vision. With measured precision calibration and cost design from running a wallpaper catalog solo.

Claude Visionimage processingduplicate detectionperceptual hashcost design4

✦ Premium Article

I was about to add sixty freshly finished wallpapers to the catalog one morning when I stopped scrolling. That blue gradient — I feel like I've shipped something close to it before.

Memory is not reliable. Somewhere in a catalog that had grown to a few thousand images, was there really a near-match, or was I imagining it? For a while I had no way to check, and I published on a quiet "probably fine."

Shipping the same wallpaper twice with only a color change reads as recycling. It costs you a little in the store's impression, and a little in daily trust. This article is about catching the near-duplicates an exact hash never sees — using a perceptual hash and Claude Vision in two stages — with the numbers from running a wallpaper catalog as a solo indie developer.

The morning an exact hash let one slip through

My first move was to compare the raw bytes of each file with SHA256. That is airtight for duplicate files: identical bytes produce identical hashes. I once built a ledger around exactly this idea to clean up duplicates on the Files API (I wrote it up in Deduplicating with content hashes on the Files API).

In the wallpaper workflow, though, it was almost useless. The reason is simple: most of what I perceive as "similar" is, byte for byte, a different file.

OperationAppearanceSHA256
Warm the color balance slightlyNearly identicalChanges completely
Trim a few percent off the edgesNearly identicalChanges completely
Re-encode on export (quality 90 to 85)IdenticalChanges completely
Downscale by 10 percentIdenticalChanges completely

An exact hash returns an unrelated value if even one pixel differs. So the case that troubled me most — looks the same, but slightly different — was precisely the one it could never catch, by design.

What I needed was a tool that measures visual closeness, not byte equality.

Why pair a perceptual hash with Vision

The classic tool for quantifying visual closeness is the perceptual hash. You shrink the image drastically, convert it to grayscale, keep only the light-dark relationships between neighboring pixels, and fold that into 64 bits. Because color tweaks and light compression preserve the light-dark skeleton, similar images produce similar hashes.

A perceptual hash alone was not precise enough, though. Loosen the threshold and you miss fewer duplicates but also pick up unrelated designs that happen to share a composition. Tighten it and you miss the recolored near-duplicates. That band — where loosening and tightening both fail — is exactly the region a human resolves at a glance but a machine struggles with.

So I split the roles. The perceptual hash stays a cheap, fast, high-volume pre-filter for narrowing candidates, and only the final "is this essentially the same?" call goes to Claude Vision. Vision is expensive, but after the narrowing it runs very few times. Earn recall with the cheap filter; recover precision with the expensive judgment. That division of labor is the heart of the design.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Catch the recolored and lightly cropped near-duplicates that an exact SHA256 match lets slip through, using a perceptual hash and Vision in two stages
✦Cost design that avoids the all-pairs comparison (a perceptual hash trims candidate pairs to about 0.03 percent before Vision) with real precision calibration
✦An abstain route that sends the gray zone to a human queue, plus a design that avoids flagging legitimate series variations as duplicates
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ API & SDK2026-10-16
Sending 40 Rows From Make to the Claude API Stops at Row 14 — Avoiding the 429 With One Subtraction
Why a no-code automation that sends spreadsheet rows to the Claude API one by one hits a 429 partway through, and how to fix it. Seven spacing strategies tested on a mock bucket, a formula for the Sleep delay, and settings that stop failed rows from vanishing.
⬡ API & SDK2026-10-14
A 429 With retry-after: 120 Makes the Anthropic SDK Try to Wait 120 Seconds
I ran the Anthropic SDK's automatic retries against a mock server in 12 scenarios. Two retries by default, retry-after obeyed with no cap, and spend-limit 429s that no amount of waiting fixes. Code for a retry wrapper with a wait cap and a time budget, plus the logs.
⬡ API & SDK2026-10-13
Haiku 5.5 is cheaper per token, but your bill jumps fivefold past about 77k Haiku 4.5 tokens
On the price sheet, Haiku 5.5 costs roughly a tenth of Haiku 4.5. But the same text becomes about 30% more tokens, and a prompt over 100k tokens is billed at five times the rate. Here is the boundary in Haiku 4.5 terms, a script I actually ran, and the changes that return a 400.