Flip a JPG losslessly
The compressed blocks are moved and their signs changed — nothing is decoded or compressed again, and the saved file is read back to prove it.
Nothing has been read yet. The two panels above are a drawing, not a file — the sign on the right is the one on the left reflected, which is the whole operation.
Open an image. Choose an axis.
The result is drawn from the same pixels, in reverse order.
Open a JPEG — its block layout is read straight away.
Nothing to hand? and watch the words reverse.
And which one this page uses
Three ways to write a flipped JPEG
Every flipped JPEG on the web is written one of three ways. Re-encode: decode the picture, flip the pixels, compress it again. Simple, universal, and a second generation of loss — the reason a JPEG flipped ten times looks worse. Tag: leave the picture alone and change the sixteen-bit EXIF orientation field, which tells viewers to show it mirrored. Nothing is lost, but a viewer that ignores the field shows the original. Blocks: move the compressed 8 × 8 blocks to their mirrored places and change the sign of the numbers that describe left-right (or up-down) detail. That is what the classic jpegtran -flip tool does, and it is what this page does by default, in the tab.
The block route has one rule that belongs to the format. Blocks are grouped into units of 8 or 16 pixels depending on the colour subsampling, and only whole units can move. If the picture’s width is not a whole number of units, the strip on the right has no partner; the page tells you its exact width and lets you leave it, trim it or switch to the tag route. A perfect flip is offered only when there is no strip.
Four steps
Running it
- Open the JPEG. The page reads its block layout straight away: the size of its block unit (8 or 16 px), its colour subsampling, and whether it is a baseline file it can move blocks in.
- Choose the axis. Left to right, top to bottom or both. The JPEG route is already set to move the compressed blocks, and the readout says whether every block can move.
- Decide about the edge, if asked. If the width (or height) is not a whole number of block units, a strip at the edge cannot move. Leave it in place, trim it off, or switch to the orientation-tag route.
- Save and check. The file is written without decoding, read back, and every coefficient compared. Check the saved file decodes it and compares it with the source mirrored.
Real numbers
A worked example
A 4032 × 3024 phone JPEG with 4:2:0 colour uses 16 px units: 4032 = 252 × 16 and 3024 = 189 × 16, so every block can move on either axis. It holds 190,512 brightness blocks and 47,628 of each colour, 285,768 in all. Flipping it left to right moves every one of them to its mirrored column, rebuilds the compression tables, and reads the result back: 0 coefficients changed. A 4000 × 3000 file flips left to right perfectly too (250 units), but top to bottom leaves an 8 px strip, because 3000 is 187½ units.
- Baseline JPEGs only. Progressive and arithmetic-coded files, 12-bit and multi-scan files are refused with the reason; the tag route or a re-encode still works.
- Reflections, not turns. Quarter turns are not written by moving blocks here; the tag route handles any of the eight orientations.
- Trimming is not reversible. A trimmed strip is gone. Leaving it keeps every pixel but leaves that strip unflipped.
- Decoders may differ by a level or two. The numbers in the file are exact; a browser's decoder can smooth subsampled colour slightly differently at block edges, which the check reports as measured rather than hides.
Asked often
Common questions
- Is this really lossless?
- The block route is: a JPEG stores 8 × 8 blocks of numbers, and mirroring a block is the same as moving it and changing the sign of half its numbers. Nothing is decoded and nothing is compressed again, so every number in the new file is one from the old file. The page reads the saved file back and confirms that 0 values changed. A re-encode is never called lossless here.
- What happens at the edge?
- Blocks only move whole. A photo 4000 px wide in 16 px units is 250 units exactly; one 4001 px wide leaves a 1 px strip with no partner on the other side. You choose: leave it where it is (it stays unflipped), trim it off (not reversible), or use the tag route, which flips everything by rewriting the orientation field instead.
- Why is the file the same size — or slightly smaller?
- The same numbers are stored, just in a different order. The compression tables are rebuilt for the new order, which is usually a few hundred bytes smaller than a camera's stock tables. A re-encode, by contrast, can land anywhere.
- Will every viewer show it flipped?
- Yes, with the block route: the stored picture itself is mirrored. With the tag route, only viewers that honour EXIF orientation show it flipped; the rest show it as it was.
- Does it keep EXIF?
- Every metadata segment is copied as it is, the orientation tag is left alone (the stored picture moved, so the same tag still applies) and the embedded thumbnail is removed, because it would show the unflipped picture. You can also erase GPS location in the same step.
Elsewhere on this site
- Lossless JPEG flips, explained
Blocks, units, the edge strip and the three routes.
- Flip an image horizontally
Any format, left to right.
- Batch flip images
The block route over a whole folder.
- Mirror a selfie
Front-camera JPEGs, flipped without loss.
Original
Blocks moved