A rotation is cheap. The corners are what cost you.
Turn a rectangle by anything other than a right angle and its four corners swing outside the old frame. A canvas holds no pixels beyond its own edges, so one of two things has to happen. Either the canvas grows and four triangular wedges of empty space open up around the photo, or the canvas stays the size it was and the corners get sliced off. Most rotation tools decide this for you in silence. Here it is a switch, and the resulting pixel dimensions sit under the preview before you download anything.
The fine angle runs in tenths of a degree because a lot of rotation work has nothing to do with quarter turns. It is a handheld shot with a sea horizon leaning by a degree and a half, or a receipt that fed into the scanner crooked, or a building whose vertical lines lean in a way the eye catches before the brain names it. On a 4000 pixel wide photo, a whole degree of overshoot is obvious. Half a degree is usually the difference between fixed and still wrong.
Right angles are free. Everything else resamples.
At 90, 180 and 270 degrees the source grid maps onto the destination grid one pixel to one pixel. Nothing is averaged. What comes back is the image you put in with its rows and columns exchanged, identical down to the byte if you save it as PNG. At 12.4 degrees no source pixel lands cleanly on a destination pixel, so the browser blends the four source pixels nearest the point each output pixel maps back to. The result is a slight softening of fine detail. On a photograph of trees or water you will not see it. On screenshot text, hairlines or a QR code you will.
The practical rule follows from that. Set the angle you want in one pass. Rotating three degrees, saving, deciding it was too much and rotating back by three degrees means the image has been resampled twice and re-encoded twice, and the second pass cannot recover what the first one blended away.
The geometry behind the growing canvas
Grow to fit computes the bounding box of the rotated rectangle, which is the same formula every image library uses:
outputWidth = width * |cos θ| + height * |sin θ|
outputHeight = width * |sin θ| + height * |cos θ|Because both terms are positive for any angle off a right angle, the canvas grows in both directions at once. A small tilt costs more area than people expect. These are the numbers for a 1600 by 900 photo:
| Angle | Canvas after fit | Pixel area vs source | What it looks like |
|---|---|---|---|
| 5° | 1672 × 1036 | +20% | Thin slivers at the corners, easy to crop away |
| 15° | 1778 × 1283 | +58% | Clear wedges, the crop starts eating real content |
| 30° | 1836 × 1579 | +101% | Twice the pixels, most of them empty |
| 45° | 1768 × 1768 | +117% | A perfect square, the photo sitting in it as a diamond |
| 90° | 900 × 1600 | Unchanged | A plain swap of width and height |
That area growth is also file size growth, since the wedges still get encoded. A PNG of a 30 degree rotation with a flat fill compresses those wedges down to almost nothing. The same rotation saved as JPG does not, because the encoder spends bytes on the hard diagonal boundary between photo and fill.
Keep size crops instead of padding
The second canvas mode holds the output at the source dimensions and lets the corners fall outside. Nothing is padded and nothing is added. You lose the four corners of the original in exchange for dimensions that stay predictable, which is what you want when the image feeds a layout expecting exactly 1200 by 630, or when a batch of rotated frames has to keep matching sizes. Watch the preview before you commit, because content near an edge disappears first.
Straightening a leaning photo
There is no auto straighten button here, and adding one would mean guessing which line in your photo was meant to be level. A shoreline, a shelf and a road all read as strong horizontals to an edge detector, and only you know which one matters. The manual pass takes about fifteen seconds:
- Switch on the thirds grid. Its horizontal lines give you a straight reference to compare against the horizon or the top edge of a table. The grid sits over the preview only and never appears in the file you download.
- Click the preview and tap an arrow key. Each press moves half a degree, which is slow enough to see the line settle.
- Stop when the reference line runs parallel to a grid line rather than when the number looks tidy. Most crooked photos sit between 0.5 and 3 degrees off.
- Download with grow to fit on, then take the file to the image cropper and trim the wedges away. Straightening always costs you a small border, and there is no way around that.
The corner fill matters more than it sounds
The fill color paints only the wedges, so at a quarter turn it does nothing at all. Transparent is the default and works if you download PNG or WebP, both of which carry an alpha channel. JPG has no alpha, so choosing it switches the fill to white and tells you so, because a transparent pixel written into a JPEG comes out black on some decoders and white on others. When the rotated image is headed for a page you already know the background color of, set the fill to that color and the seam disappears.
The orientation flag your phone writes
Cameras and phones rarely rewrite pixels when you turn them sideways. They store the frame as the sensor read it and add an EXIF orientation tag saying which way is up. Photo apps read the tag. Plenty of other software does not, which is the reason a picture looks fine in your gallery and appears on its side after you email it or drop it into a form.
Rotating here settles the question. The image is drawn into a canvas at the orientation your browser shows, and the file that comes back holds pixels in that arrangement with no tag attached. The upside is an image that reads the same everywhere. The cost is that the rest of the metadata goes with it. Check the metadata viewer first if the shooting data, GPS position or color profile matters to you.
What runs where
- The file is read locally. FileReader hands the bytes to an image element, the browser decodes it, and the page issues no network request afterwards. Disconnect after the page loads and every control keeps working.
- The preview is a scaled copy. It renders at screen size for speed, so the on screen result is a smaller version of the real one, not the file itself.
- Download renders at full resolution. A fresh canvas at the true output size is drawn and encoded at that moment, so what you save carries the source detail rather than the preview detail.
- Nothing persists. Closing the tab clears the image. There is no history and no autosave.
Where this rotator stops
- Rotating a JPG is not lossless here. Command line tools like jpegtran turn a JPEG by 90 degrees by rearranging its compressed blocks, with no re-encoding at all. This page decodes to pixels and encodes again, so a quarter turn saved back to JPG loses a small amount of quality. Save as PNG to avoid it, or use a lossless rotator when the file is precious.
- Metadata does not survive. A canvas holds pixels and nothing else, so EXIF fields, ICC color profiles, GPS coordinates and copyright tags are absent from the output.
- One image at a time. There is no batch queue and no folder mode.
- Animated files lose their animation. An animated GIF or WebP decodes to its first frame, and that single frame is what gets rotated.
- SVG rasterizes. Vector input is drawn at its intrinsic size and comes back as pixels. Rotate the vector in an editor if you need it to stay a vector.
- Very large images hit memory limits. A decoded image needs width times height times four bytes, so a 12000 by 8000 pixel file wants roughly 384 MB before the rotation is drawn, and grow to fit needs a second buffer larger than the first. Phones give up well before desktops do.
- WebP output depends on the browser. Recent versions of every major browser encode it. Older ones quietly fall back to PNG.
- No perspective correction. Rotation turns the whole frame around its center. Converging vertical lines in a photo of a tall building are a lens problem, and no amount of rotation fixes them.
