Fix it now
- Drop the file
- Repair runs locally
- 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 signature — 89 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 withCRC 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 0Afor a lone0A(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.