Repair a corrupt PNG screenshot

A PNG is the most self-auditing image format there is: every block inside it carries its own CRC-32 checksum. That structure means some of the damage that keeps your screenshot from opening is a clean, deterministic fix, and some of it has quietly taken the lower rows for good. This tool reads the chunks and checksums locally and tells you which is which.

Your file never leaves your device — repair runs in your browser. 0 bytes uploaded.

Your data is the big block — usually intact. What breaks is the small index. Repair rebuilds it.

Drop a file here or browseTap to choose a file

ZIP · Office · PDF · video · JPG · PNG · RAR/7z · SQLite — repaired right here in your browser. Nothing is uploaded

0 bytes uploadedFree: 3 repairs/day — up to 500 MB video, 100 MB docs & archives, 50 MB photos. Free download. Single repair €5.90. No account required.

Fix it now

  1. Drop the file
  2. Repair runs locally
  3. Download the result

When a screenshot saved as .png won't open, the viewer is usually strict about something the format lets it check exactly. Windows Photos says "It looks like we don't support this file format" or "This file can't be opened"; macOS Preview says the file "may be damaged or use a file format Preview doesn't recognize"; libpng-based tools throw IDAT: CRC error, IHDR: CRC error or Not a PNG file. Drop the file above and the tool walks it chunk by chunk in your browser — verifying each CRC, checking the 8-byte signature and the IHDR geometry, and decoding the DEFLATE stream as far as it survives — then rewrites a valid file around whatever is genuinely there. Nothing is uploaded; a screenshot often shows a bank balance, a private message or a medical portal, and it never has to leave your machine to be checked.

How a PNG screenshot is built

Every PNG opens with the same 8-byte signature89 50 4E 47 0D 0A 1A 0A — a fingerprint deliberately loaded with tripwires: the high-bit byte 0x89 catches 7-bit-clean channels, the 0D 0A and lone 0A catch line-ending conversion, and the 1A (DOS end-of-file) stops a careless type from dumping the rest. After it comes a run of chunks, each a tidy package: a 4-byte big-endian length, a 4-byte ASCII type, the data, and a 4-byte CRC-32 computed over the type and data (never the length) using the standard reflected polynomial 0xEDB88320.

Three chunks carry the picture. IHDR is first and always 13 bytes: width (u32), height (u32), then single bytes for bit depth, colour type, compression method, filter method and interlace method. A modern OS screenshot is almost always 8-bit, non-interlaced, colour type 2 (truecolour) or 6 (truecolour with alpha). IDAT holds the image, sometimes split across several consecutive IDAT chunks; inside sits a zlib stream (header byte 0x78) of DEFLATE-compressed filtered scanlines — each row prefixed by a filter byte 0–4 (None, Sub, Up, Average, Paeth), written top to bottom. IEND is the empty end marker with a fixed CRC of AE 42 60 82.

Screenshots also carry recognisable ancillary chunks — lowercase first letter marks them optional — such as pHYs (pixel density, so a Retina grab reports its scale), iCCP or sRGB (colour profile), tEXt/eXIf (metadata the capture tool stamps). These can be damaged or dropped without losing a single pixel, because a decoder is allowed to skip any ancillary chunk it doesn't understand.

The damage that's a clean, deterministic fix

Because each chunk is self-checking, a whole class of PNG damage has a knowable answer rather than a guess:

  • Wrong checksum, right data. The commonest false alarm: a chunk's bytes are intact but its stored CRC no longer matches, so strict decoders (and pngcheck) reject the file with CRC error in chunk IDAT. Recomputing the CRC-32 from the data and writing it back makes the file valid again with zero loss — the checksum was the only thing wrong.
  • Zeroed or scrambled dimensions. If IHDR's width or height is zeroed, no decoder can allocate a canvas and the file won't open. But IHDR carries its own CRC, computed back when the numbers were correct. That lets the repair brute-force the geometry: try candidate width/height values, recompute the chunk CRC for each, and stop when it matches the stored value. The original dimensions fall straight out of the arithmetic — no guessing.
  • Newline / text-mode mangling. A screenshot pushed through an FTP client in ASCII mode, a chat bridge, or a script that rewrote it as text swaps every 0D 0A for a lone 0A (or the reverse), corrupting bytes throughout. The signature is designed to detect exactly this, and when the substitution is consistent it can be reversed byte-for-byte.
  • Missing or broken IEND. A file that is otherwise complete but lost its trailing end marker trips "incomplete file" warnings; rewriting a valid IEND lets a strict decoder accept the image that is already all there.

The damage that costs you rows

The honest limits start where the pixel data itself is gone, and screenshots hit both.

Truncation — the top comes back. This is the most common way a screenshot breaks: a save interrupted by a full disk, a copy cut off when a phone unplugged, a cloud-sync that stopped at 80 percent. The front of the file is intact and the tail — usually including IEND — is simply absent. Because the scanlines are written top to bottom, a truncated PNG salvages into the upper part of the image: real pixels down to where the data ends. The repair rewrites a valid trailer so a decoder accepts the file and draws what survived. The rows below the cut are not damaged, they are absent, so no tool can return them — the result is an honest partial.

Mid-stream IDAT damage — the bottom is noise. When corruption lands inside the DEFLATE stream rather than at the end, the reason it is unrecoverable is DEFLATE itself: it is one continuous stream where each part depends on what came before, with no periodic markers to resynchronise on. Once the decoder hits the bad byte it loses the thread (zlib reports incorrect data check / invalid distance too far back), and everything after it decodes as noise. A single flipped byte partway down can cost every row beneath it, not just one line — the picture is clean above the hit and garbage below. This is why a screenshot opens with a sharp top and a smeared or grey lower half, the same shape of result a truncated JPEG gives.

Compare this with formats that keep an index separate from their data — a QuickTime video's moov, a SQLite b-tree — where rebuilding the map rescues the whole file. PNG keeps its pixels in one indivisible DEFLATE stream, so a mid-stream wound is permanent below the cut.

What this can and can't fix

Can fix

  • A chunk whose stored CRC-32 no longer matches otherwise-intact data — the CRC is recomputed and the file validates with zero loss
  • Zeroed or scrambled IHDR width/height, recovered by brute-forcing candidates against the chunk's own stored CRC
  • Newline / text-mode mangling (CR-LF ↔ LF) from an ASCII-mode transfer or a script that rewrote the file as text
  • A missing or malformed IEND end marker on a file whose image data is otherwise complete
  • A truncated screenshot: the top rows that were actually written decode back as real pixels

Can't fix

  • Image rows below a mid-stream IDAT hit — DEFLATE cannot resynchronise, so everything after the damaged byte is noise
  • The rows below the cut in a truncated file — those pixels were never written, and no tool can invent them
  • A file that reads as 0 bytes or all zeros — there is no image to rebuild (that is a data-recovery job, not a repair)
  • A screenshot another app re-encoded or re-compressed after the damage — the wrong pixels are now baked in
  • Pixel-exact restoration of a garbled lower half — repair returns an honest partial, not the grey rows back

If a repair fails, we tell you why (missing data versus broken structure), and you are never charged for a failed repair.

FAQ

Why won't my PNG screenshot open?

Usually one of three things: the 8-byte signature at the front was altered, so viewers don't recognise the file as a PNG; the IHDR header that stores width and height is zeroed or scrambled, so a decoder can't set up a canvas; or the compressed IDAT data was truncated or corrupted partway. The first two are often deterministic fixes because PNG stores a CRC-32 for every chunk. The third is where the honest limits begin.

What does an "IDAT: CRC error" mean?

Every chunk ends with a four-byte CRC-32 computed over its type and data. When a decoder recomputes it and the value doesn't match, it reports a CRC error — the bytes in that chunk changed since the file was written. If only the stored checksum is wrong and the data is intact, recomputing it fixes the file outright. If the data itself changed, the CRC is doing its job by warning you, and how much is recoverable depends on which chunk was hit.

Can a truncated screenshot be recovered?

Partially, and only the top. PNG writes its scanlines top to bottom inside one DEFLATE stream, so a file cut short decodes cleanly down to where the data ends, then stops. You get the upper portion of the image back as real pixels; a valid IEND is rewritten so a viewer will accept it. The rows below the cut were never in the file, so no tool can restore them.

Why is the bottom of my screenshot grey or garbled?

Because DEFLATE, the compression PNG uses, is a continuous stream with no way to resynchronise after damage. If the corruption lands in the middle of the IDAT data rather than at the end, the decoder loses the thread at that byte and everything after it decodes as noise, not just one row. That is why mid-stream damage typically costs every row below the hit, while clean truncation at least leaves the top intact.

Is my screenshot uploaded to be repaired?

No. The file is read from your disk and rebuilt in your browser tab; the chunk walk and CRC checks are plain code running locally. You can open the Network tab and confirm 0 bytes leave — which matters when a screenshot shows a bank balance, a private chat, a password or a medical portal.

Related: Repair a JPEG photo · PNG chunks & CRCs, explained · Verify the zero-upload claim