Convert a phone photo from JPG to PNG and the file usually grows four or five times, with no visible change at all. It looks like the conversion did something wrong. It did exactly what PNG promises, which is to store every pixel without losing any of them, and a photograph turns out to be one of the hardest things there is to store that way.
Lossless Means Every Pixel, Including the Noise
JPEG is small because it decides what you will not notice and discards it. Most of what it discards is high-frequency variation: the grain in a sky, the texture of skin, sensor noise in the shadows. The decoded JPG is not the photo the camera captured. It is a close approximation, and the approximation is a different set of pixels from the original.
PNG makes no such decisions. Decode it and you get back exactly the pixels that went in. So when a JPG becomes a PNG, the PNG has to record the JPG's approximation precisely, down to the faint 8×8 block patterns and the ripple around each edge that JPEG compression left behind. None of that was costly for JPEG to produce, and all of it is costly for PNG to store.
Step One: Filters Turn Pixels Into Differences
PNG compression happens in two stages, both defined in the W3C PNG specification. The first works row by row. Before compressing a row, the encoder may replace each byte with the difference between it and a nearby byte that has already been encoded, choosing one of five filters per row.
In a smooth gradient, neighbouring pixels are nearly equal, so the differences are small numbers clustered around zero, and small repetitive numbers are what the second stage compresses best. The filters do not reduce the data. They rearrange it into something more predictable.
PNG's Five Filter Types
a is the byte to the left, b the byte above, c the byte above and to the left. Each filter stores the current byte minus its prediction.
| Type | Name | Prediction |
|---|---|---|
| 0 | None | Nothing, the byte is stored as is |
| 1 | Sub | a, the pixel to the left |
| 2 | Up | b, the pixel above |
| 3 | Average | The average of a and b, rounded down |
| 4 | Paeth | Whichever of a, b or c is closest to a + b − c |
The Paeth predictor guesses which edge the pixel is on
Alan Paeth's predictor computes p = a + b − c, which is what the pixel would be if the image were a perfectly smooth plane, then picks whichever of the three real neighbours is nearest to it. On a vertical edge it ends up choosing the pixel above, on a horizontal edge the pixel to the left. It is a small piece of logic that works out the local direction of the image for every byte, and it is often the best filter for photographs.
Step Two: DEFLATE Looks for Repeats
The filtered rows are compressed with DEFLATE, the algorithm in zip and gzip, specified in RFC 1951. It has two parts. LZ77 scans for sequences that already appeared within the last 32 KB and replaces each with a short back-reference, length and distance. Huffman coding then gives the most frequent symbols the shortest codes.
Both parts reward repetition. A screenshot is full of it: rows of identical background pixels, the same button drawn twice, text in one color. After the Up filter, a run of identical rows becomes a run of zeros, which costs almost nothing.
A photograph has almost none. Even after the best filter, the differences are a scatter of small random numbers, because noise is random by definition. LZ77 finds few long matches in random data, and Huffman can only shorten codes so far when the values are spread out. A JPG adds its own faint block artefacts on top, which are not random to the eye but are not repeated exactly either. The result is a PNG close to the raw size of the pixels.
What the Numbers Look Like
A 12-megapixel photo is 4032 × 3024 pixels. Stored raw at three bytes per pixel, that is about 36.6 MB. As a JPG at quality 85 it is typically 2 to 4 MB, roughly a tenth to a twentieth of raw. As a PNG made from that JPG it is usually 15 to 20 MB, around half of raw, because filters and DEFLATE recover only part of the space on photographic content.
A 1920 × 1080 screenshot of a code editor is about 6.2 MB raw. As PNG it is commonly 100 to 300 KB, because almost every row repeats something. The same screenshot as a JPG may be no smaller, and it has ripples around every character. That is the whole case for PNG in one comparison: it wins decisively on flat, repetitive images and loses decisively on photographs.
Convert JPG to PNG for editing or uploads
Lossless from here on, orientation applied, up to fifty photos in one ZIP.
When Converting a JPG to PNG Is the Right Call
The size cost is real, so the reasons need to be too.
You will edit and save it several times
Each time a JPG is opened, changed and saved, it is compressed again, and any crop, resize or color change pushes its coefficients off the grid they were rounded to. Converting to PNG once, editing as PNG, and exporting a single JPG at the end means only one more lossy step instead of one per save.
Something downstream demands PNG
App stores, marketplaces and design handoffs often require PNG so that their own processing starts from a lossless file. A PNG made from your JPG meets that requirement exactly, with nothing further lost.
You need to add transparency
A JPG cannot hold an alpha channel, so cutting out a background has to happen in a format that can. Converting is the first step. The cut-out itself still has to be done in an editor.
The JPG is really a graphic
A diagram or screenshot that someone saved as JPG will grow far less as PNG, and every further copy will stay exact. It will not lose the ringing JPEG already added, though.
What Else Changes in the Conversion
Orientation. Phones often store the pixels sideways and record the correct rotation in the EXIF Orientation tag. A converter that respects the tag rotates the pixels themselves, so the PNG is upright everywhere, including in programs that ignore EXIF.
Metadata. EXIF data, including camera model, date and GPS position, is not carried into a PNG that was written from a canvas. PNG can hold EXIF in an eXIf chunk, but a browser's encoder does not write one.
Color. A canvas works in sRGB. A JPG tagged with a wider profile such as Display P3, which recent iPhones use, is converted to sRGB on decode, which can slightly flatten the most saturated reds and greens on a wide-gamut screen. For ordinary photos and screens the change is not visible.
Frequently Asked Questions
Related Tools
Keep Reading
PNG to JPG Without Black Backgrounds or Halos Around the Edges
Transparent pixels are stored as zero, which is black. The compositing formula behind every flattened logo, and the PNGs that should never become JPGs.
Serving WebP on Your Site: picture, Accept Headers and the Vary Trap
The picture element or server negotiation, and the one missing header that lets a cache hand WebP to everyone. Plus where the JPG should stay.
What the JPEG Quality Slider Is Really Doing to Your Photo
Quality 80 scales the quantization tables to 40 percent, it does not keep 80 percent of the picture. Where the setting stops being free, and why PNG has no dial.