Pixel Perfect Checker

Measure the pixel size, grid offset, blurred edges and colour count of an upscaled sprite.

A pixel-perfect checker tells you what state a pixel-art image is in: already 1×, an exact integer upscale (with its factor and grid offset), a fractional or smooth resize, or blurred. Nerulio’s checker finds the rows and columns where the colour changes: if they all sit on multiples of 3 (after one common offset), the image is exactly 3× and the 1× source can be recovered pixel for pixel. Anything else is reported as a measurement with a “not confident” flag where needed — never repaired as if it were exact.

Drop image files hereProcess many files at once
No upload · processed on this device

How the checker decides, without sampling or guessing

Integer detection is arithmetic. In a clean k× upscale the colour only changes at block borders, so every changing column index leaves the same remainder when divided by k, and so does every changing row. The checker records those positions in one pass and tries k from 16 down to 2; the largest k that fits both axes is the scale, a grid starting at 0 is preferred, and a shared non-zero remainder is the offset of an off-grid crop.

Without an integer grid, runs of identical colour give an estimate. A 2.5× nearest resize alternates runs of 3 and 2 pixels, so the mean of the shortest runs (those within 1.5× of the minimum) reads 2.500×. Averaging every run over-estimates, because a flat border is one long run of many blocks: 2.885× on the same test sprite.

Blur shows as in-between colours: an edge pixel whose colour lies strictly between its two opposite neighbours in Oklab. Nearest-scaled art has none; the bilinear 2.5× version of the test sprite had 1243 such pixels (86.3 % of its edges) and 700 partially transparent ones. One noisy pixel inside a block is enough to break the exact proof — which is why JPEG images are never reported as exact integer upscales.

Scale
Screen pixels per art pixel: exact for a proven block grid, an estimate otherwise.
Offset
Pixels cut from the left and top of the grid; a 4× sprite cropped by 2 and 3 pixels reads offset 2, 3.
In-between pixel
An edge colour between its neighbours — evidence of smoothing.
Not confident
A one-colour image, or one that changes on only one axis, has no grid to measure.

Example: one 16 × 16 sprite, four versions

Reports for a 16 × 16 test sprite after different treatments:

input                              report
64 × 64   4× nearest               scale 4 (exact), offset 0, 0, logical size 16 × 16
62 × 61   same, cropped 2 and 3 px  scale 4 (exact), offset 2, 3, off-grid
40 × 40   2.5× nearest             no integer grid, estimate 2.500× (runs 3, 2, 3, 2 …)
40 × 40   2.5× bilinear            not integer; 1243 in-between edge pixels (86.3 %)

recover 1× of the crop: ceil((62 + 2) / 4) × ceil((61 + 3) / 4) = 16 × 16

The 2.5× versions have no exact 1× inside them: blocks are 2 and 3 pixels wide in turn, so the checker offers no recovery and points to the cleanup instead.

Check the result

  • For an exact result, the logical size is ceil((width + offset) ÷ scale) on each axis.
  • Upscale the recovered sprite by the same factor: for an uncropped input it matches the input pixel for pixel.
  • A “not confident” result on a flat or striped image is correct — there is nothing to measure.

Troubleshooting

SymptomLikely causeHow to checkFix
Reads 1× although the image is clearly enlargedSmoothing or JPEG removed the flat blocks, so no integer grid existsThe blur count shows many in-between edge pixelsUse the Cleanup panel (downscaler), which measures smooth and fractional resizes
Reads 2× for art you believe is 4×Some colour changes sit between the 4-pixel borders: the art was edited after upscaling, or it has 2-pixel detailsZoom into the edges that break the 4-pixel gridAccept 2×, or remove the later edits first
An estimate such as 2.500× but no Recover buttonA fractional scale: blocks have two widths, so no exact 1× existsThe report says “no integer grid”Rebuild 1× in the Cleanup panel, which cuts at the measured edges
“Not confident”One colour, or changes on one axis onlyLook at the image: a flat fill or stripesNothing to fix; check a frame with detail

Other ways to do it

OptionWhen it is the better choice
Cleanup panel in the Pixel workspaceThe image was resized by a fraction, smoothed, JPEG-compressed or generated: it measures those grids and rebuilds 1× as a new sprite.
A grid overlay in any pixel editorOne clean image: set the grid to the block size you see and check that every edge falls on it.

What this page does not cover

  • Integer scales up to 16× are detected (and never more than the image’s shorter side).
  • The exact proof needs exact colours: one noisy pixel inside a block and the image is reported as not an integer upscale.

Versions and sources

Checked in the Pixel Lab tests (Chromium): 1×, 2×, 3×, 4× and 8× nearest detected exactly; a 4× sprite cropped by 2 and 3 px read offset 2, 3; 2.5× nearest read 2.500×; a 3× sprite recovered to 16 × 16 pixel-identical.

Pixel Perfect Checker

Measure the pixel size, grid offset, blurred edges and colour count of an upscaled sprite.

How it works

  1. Add images
  2. Adjust settings and review the result
  3. Download a new file

Supported formats

PNG / JPG / WebP / AVIF / HEIC → PNG + JSON (ZIP) — Input decoding depends on browser support and optional engines.

What this tool does

Measure an upscaled sprite’s real pixel size, grid offset, blurred edges and colour count.

Implementation and verified quality

advanced · colour-change residues for integer block grids / run lengths / Oklab edge interpolation count. Quality qualification is in progress. Pro/Flagship quality has not been established.

Before you export

Only an integer block grid is proven exactly; a non-integer factor is reported as a run-length estimate, not a fact.

Frequently asked questions

What are this tool’s limitations?

Only an integer block grid is proven exactly; a non-integer factor is reported as a run-length estimate, not a fact.

Are my files uploaded?

This tool processes the files you open on your device without uploading them. Images you explicitly attach to community posts are uploaded separately. Optional engines and models are downloaded from third parties; those requests expose connection information such as your IP address.

Will my work be saved automatically?

No. Images and editing state stay in this tab; media output can use local temporary storage. Changing language preserves your work; reloading, closing the tab, or following a link to another page can clear it.