How to use it
- Drop the HEIC files or pick them. Each file is checked by content: a JPG with a .heic name is offered unchanged, PNG/WebP/AVIF files are pointed to the Image Converter, videos are skipped.
- Keep quality 90 % or choose a preset, and limit the longest side if you need smaller files.
- Press Convert. Each row shows the new pixel size, file size and any notes (HDR, transparency, several images in the file).
- Download a file from its row, or everything as one ZIP. Changing the settings afterwards offers a one-click re-conversion.
Example
A 12 MP iPhone photo (4,032 × 3,024 px, 2.1 MB HEIC with Display P3 profile and GPS tags) converted at quality 90 % comes out as a 4,032 × 3,024 px JPG of about 3.5–4.5 MB, with the P3 profile embedded and no GPS or camera tags. With the longest side limited to 1920 px the same photo becomes a 1,920 × 1,440 px JPG of roughly 600–800 KB. On a 16-core desktop a batch of 24 such photos takes about 20 s (two parallel workers); on a phone the batch runs one photo at a time.
How the conversion works
A web worker fetches the libheif 1.23.2 WebAssembly build (libheif-js) from jsdelivr, with unpkg as a fallback, and verifies the SHA-256 of both files against the values pinned in the source; a mismatch aborts with an “engine integrity” error instead of running unknown code. The file type is detected from the ISO-BMFF ftyp brands, not the extension. libheif decodes the primary image item (not the first top-level item, which in multi-image files can be a secondary picture) and applies the HEIF irot/imir/clap transformations. The EXIF Orientation tag is intentionally not applied and not written: iPhones store the rotation in both places, so honouring both would rotate the photo twice.
Pixels are encoded with the browser's own JPEG encoder on an OffscreenCanvas; if the canvas is unavailable or too large (iOS Safari caps canvases at roughly 16.7 MP, below a 24 MP iPhone 15 Pro photo) a pure-JavaScript encoder (jpeg-js) takes over at the same resolution. The JPEG header is then rebuilt so that only the JFIF segment and the colour profile remain: the original ICC profile (Display P3) is copied through, and for files that only signal P3 or BT.2020 throughnclx codes a matrix/TRC ICC v2 profile is generated. HDR (PQ/HLG, Apple gain map) photos are converted at SDR brightness and flagged. Transparent areas are flattened on white. Worker memory is recycled above 640 MB, and a second worker is used only on desktops with at least 4 cores and 8 GB.
Sources: libheif on GitHub (LGPL-3.0), libheif-js on npm (WebAssembly build), ISO/IEC 23008-12 – HEIF (overview), ITU-T H.273 – colour primaries and transfer characteristics codes.
Limits
- Images above 100 megapixels are refused (decoding needs 10–14 bytes per pixel); 40–100 MP photos work but are slow on phones.
- HEIF files with codecs other than HEVC (for example AV1-coded AVIF, or JPEG-in-HEIF) are reported as unsupported; AVIF can be converted with the Image Converter.
- Live Photo videos (.mov) are not photos and are skipped; HEIC bursts and multi-image files yield the primary picture only.
- Everything is held in browser memory: download and clear the list between very large batches.
Questions
- Why does Windows or my website not open HEIC files?
- HEIC uses the patented HEVC codec, which Windows, many browsers and most content-management systems do not ship. JPG is supported everywhere, which is why converting is the usual fix.
- Are my photos uploaded to a server?
- No. The only network request is the one-time download of the libheif decoder from a CDN; the photos are decoded and encoded inside a web worker in your browser and never leave your device.
- Does the JPG keep the date, camera and GPS data?
- No, on purpose. The converter writes a fresh JPEG with only the colour profile. If you need the EXIF data, keep the original HEIC alongside the JPG, or use a desktop tool such as ExifTool to copy tags.
- Why does a photo come out rotated correctly without an orientation tag?
- libheif applies the rotation stored in the HEIF container, so the pixels are already upright. Because no EXIF Orientation tag is written, viewers do not rotate the image a second time.