The darkroom · Convert
Convert an image to WebP, JPEG or PNG — in the browser
Your browser contains picture decoders, and picture encoders behind its canvas. This page puts them to work on your own files: a photo is decoded, drawn on a canvas at its full size and handed to the encoder for the format you chose. The new file is made on your device.
WebP, JPEG, PNG · AVIF where the browser can write it · quality 1–100 · a batch as one ZIP · 0 bytes uploaded
The tray
Drop them in. Read them. Clean them.
Each photograph gets a card: what the file really is (by its bytes, not its name), its size, and a flag for every thing in it that points at a place or a person. What it says opens the lot, tag by tag. Strip takes the metadata out and leaves the picture exactly as it was; Develop writes a new file in the format and size the developer is set to. Beside the tray, the bench holds the other tools — the Exif viewer, Convert, Resize, Compress and Crop. Several photos at once is the point: the buttons under the drop zone do the whole tray.
The tray
Empty — nothing read yet
Drop photographs hereYour photographs, read here
JPEG, PNG and WebP; HEIC and AVIF where this browser can decode them. Or paste an image. Nothing is uploaded.
The tray is empty. Choose some photographs, drop them anywhere on this page, paste one, or try the sample — a picture drawn by this site whose metadata was written by hand the way a phone writes it.
A batch lives in this tab’s memory until you clear it or close the tab. Nothing is written to the browser’s storage except the developer’s settings.
Convert
Four formats, and what each keeps
Write as
| Write as | Kind | Transparency | Quality slider |
|---|---|---|---|
| JPEG | Lossy | None: transparent areas are filled with the colour you choose | Yes |
| PNG | Lossless | Kept | No |
| WebP | Lossy, as written here | Kept | Yes |
| AVIF | Lossy, as written here | Kept | Yes — only if this browser has an AVIF encoder |
The page does not assume what your browser can write. When it loads, it asks the canvas for a tiny WebP and a tiny AVIF and looks at what comes back; the HTML standard says a browser that does not support a format answers with a PNG instead. A format your browser cannot write is switched off, and the line above the buttons names what it can. Many browsers today have no AVIF encoder behind the canvas, so on most of them AVIF stays off, and the page says so rather than hand you a PNG called AVIF.
What you can put in
Anything this browser can decode: JPEG, PNG and WebP everywhere this page runs, and HEIC or AVIF where the browser has the decoder. If it has not, the card says the browser cannot decode HEIC, still shows you the file’s metadata, and converts nothing — it never pretends.
What conversion changes
Metadata. None of it is carried over. The new file is written from pixels, and a canvas has no EXIF, no GPS and no XMP to give; the page reads the new file back to show that. Converting is therefore one more way to get a clean copy — at the cost of re-encoding.
Rotation. The picture is decoded the right way up, following its Orientation tag, so the new file needs no tag. Colour. A canvas works in sRGB unless asked otherwise, and this page does not ask. A picture in a wider colour space is converted to sRGB when it is drawn, and the original’s ICC profile is not carried into the new file; some browsers write a standard sRGB profile of their own, and the card says when one did.
Quality. The slider’s number, 1 to 100, is what the encoder is given on the standard’s 0.0-to-1.0 scale. What an encoder does with a given number is its own business: the same number does not mean the same thing to a JPEG encoder and a WebP encoder. Animation. One canvas makes one still picture, so an animated file comes out as its first frame.
A batch, and the limits
Add many photos and press Convert all: each comes out in the chosen format, on its own card, and Download all packs every result into one ZIP written in the page. A canvas has a maximum size that depends on the browser and the device. Before drawing, the page makes the canvas, puts one pixel in its far corner and reads it back; if the pixel is not there, the canvas is past the limit, and the page tells you so instead of writing an empty picture. Pictures over 100 megapixels are not decoded at all, and files over 300 MB are not read. To change nothing but the metadata, strip it losslessly instead.
How to check that nothing is uploaded. The page’s own scripts make one request of their own — the sample card, from this site, when you press for it — and none that carries a file. The folder is served with a Content-Security-Policy header that lets the page connect only to this site and to Google’s analytics hosts, so even a mistake here could not send a photo anywhere else: the browser would refuse it. Open the developer tools, choose the Network tab, clear it, then add a photo and run the tool, and watch. Google’s analytics counts the visit and that a tool was used; nothing in this page hands it a file name, a pixel or a tag.
The other tools
One tray, seven tools, a page for each.
Every tool page carries this same tray and opens the bench on its own tool; the tabs switch tools in place, so the photos already in the tray stay where they are. Each page says more about its one job.
- The darkroomThe tray and all seven tools on one page, with the whole method.
- Exif viewerEvery tag in a photo named and decoded — camera, lens, date, the GPS position — with XMP, IPTC and the colour profile.
- Remove EXIF and GPSAll the metadata, or only the location, out without re-encoding: the picture’s bytes are copied and read back.
- ConvertTo WebP, JPEG or PNG with the browser’s own encoder — and AVIF where it can write it.This page
- ResizeFit photos inside a box of pixels, or set an exact size — one or a batch, as one ZIP.
- CompressA quality slider that shows the new size in bytes before you download.
- CropDrag a frame or type exact pixels; hold 1:1, 4:3, 3:2, 16:9 or 4:5.
Method
What is read, what is written, and what is sent: nothing.
Fetched, computed, sent
There is no upstream and no server doing the work. The page loads its own files from this site, and the sample card from this site when you ask for it; your photographs are read from disk into this tab’s memory, worked on there by the page’s own readers and the browser’s own decoders and encoders, and handed back as downloads made in that memory.
The folder is served with a Content-Security-Policy header whose connect-src allows
this site and Google’s analytics and ad-measurement hosts —
*.google-analytics.com, analytics.google.com and
*.analytics.google.com, *.googletagmanager.com, www.google.com
and its country domains, and stats.g.doubleclick.net — and nothing else. The full
method — every format read by hand, every limit, every source — is on
the darkroom’s front page.
Sources for this tool
- WHATWG HTML — the canvas element: sRGB by default, quality from 0.0 to 1.0, and how a browser answers a format it cannot write. Read 2026-09-28.
- MDN — <canvas>: maximum canvas size: the iOS limit of 4,096 × 4,096 pixels. Read 2026-09-28.
- MDN — createImageBitmap(): decoding upright, by the EXIF orientation, and to a smaller size. Read 2026-09-28.
- Google — WebP Container Specification: RIFF chunks, the VP8X flags, EXIF, XMP and ICCP. Read 2026-09-28.
- W3C PNG Specification, Third Edition: chunk types and eXIf. Read 2026-09-28.
- PKWARE — .ZIP File Format Specification: stored entries, CRC-32, UTF-8 names. Read 2026-09-28.