Format Converter
Convert between JPG, PNG, WebP, BMP, TIFF, and AVIF.
Format Converter re-encodes images into another format with quality control — one file or up to 50 at a time, per the card: "Convert JPEG, PNG, WebP, AVIF, BMP, GIF, and iPhone HEIC/HEIF — one image or 50 at a time. Runs entirely in your browser." Inputs are an explicit allowlist; anything else is skipped with a toast. Pick an Output Format, move Quality when the target is lossy (it hides for PNG and BMP), hit Convert, and compare Original Size against Converted Size before downloading.
Exactly one file keeps the classic screen: live preview with dimensions, a four card stats grid (Original Size, Converted Size, Dimensions, Output Format), and a single Download. Two or more files switch to the batch screen: a selection header showing two thumbnails with "+N more images", a scrollable file list with per file remove, and a Convert N Images button. Batch results offer per file downloads or one "Download All (ZIP)" built with JSZip. Everything runs locally.
HEIC input works even though no browser except Safari can decode it natively. A single HEIC decodes immediately on select so its preview works; in a batch, HEIC files decode during the convert loop one at a time, watched by an inline progress bar reading "Converting 3 of 12 — beach.heic" while the current file row shows a spinner and finished rows flip to a green check (failures get a red X). The page scrolls the progress panel into view when you press Convert and back to the results header when the run finishes. Browser capability matters for modern formats: amber warnings like "⚠ AVIF encoding may not be supported in this browser. Falls back to PNG if unsupported." appear only when a 1×1 canvas sniff says the encoder is missing. Transparency is flattened to white for JPEG/WebP/AVIF targets.
How it works
On file select, isSupportedImageFile checks the allowlist (MIME type first, then file extension, so extension-only picks still land). Non-matching files are dropped with a "Skipped n files" toast. The batch is capped at MAX_BATCH_SIZE = 50 with a toast when exceeded.
Single file selection routes through getImageDimensions and, for HEIC, through decodeHeic — a code-split dynamic import of heic2any that converts the blob to PNG, powers the preview, and is kept as item.decodedFile so the canvas re-encode and the Original Size stat both see the right bytes.
Batch selection stores files without decoding; viewable files get an object URL for thumbnails, HEIC rows show a placeholder badge ("HEIC · decodes on convert"). Converting runs sequentially — bounded memory, one heic2any WASM instance at a time — dispatching progressSet per file so the inline bar above the Convert button climbs and deriveRowStatus turns each row into pending, active, done, or failed while remove, Clear All, and Add More stay disabled. A failed file is recorded and the loop continues; the final toast reports "Converted 11 of 12 images. Failed: broken.jpg".
The normal pipeline loads the image, fills a white background when the target is JPEG, WebP, or AVIF (alpha flattened), draws the image, and calls canvas.toBlob(format, quality). detectBrowserAVIFSupport and detectBrowserWebPSupport probe with a 1×1 canvas and stash results in formatConverterSlice so the amber warnings only appear when relevant. GIF input converts the first frame only. Batch results sum original and converted sizes into a total with a signed delta (format conversion can grow files, for example PNG to BMP).
How to use
- Drop images or use the dropzone; accepted formats are JPEG, PNG, WebP, AVIF, BMP, GIF, and HEIC/HEIF. Unsupported picks show a skip toast.
- With one file you get the single screen: HEIC shows a "Decoding HEIC in your browser…" spinner, then a preview with dimensions. "Change file" swaps it, and picking several files there moves you into the batch screen.
- With two or more files the batch screen appears: the header shows up to two thumbnails, the file count, total size, and "+N more images". Remove rows one by one or use "Clear All"; "Add More Files" appends up to the 50 file cap.
- Pick "Output Format": JPEG, PNG, WebP, AVIF, or BMP, and heed any AVIF/WebP browser-support warning.
- Adjust "Quality" for non-PNG/BMP formats (the slider hides for lossless targets).
- Click "Convert" (or "Convert N Images"). The page scrolls to the settings panel, which shows an inline bar with "Converting k of n — filename" and a percent; each file row updates live with a spinner, then a check or an X. The list stays visible the whole run.
- Single file results show the four stat cards; batch results show a total summary plus per file rows.
- Download one file, or use "Download All (ZIP)" for converted_images.zip. "Convert More" returns to the list with your settings intact; "Start Over" clears everything.
Tips
- HEIC files convert fully offline — heic2any is bundled and dynamically imported, so the decoder chunk only loads when a HEIC file is actually involved.
- In a batch, HEIC thumbnails appear after the convert pass, when each file is decoded; selection stays instant even with dozens of HEIC photos.
- The Original Size stat always reflects the file you picked, even when conversion ran from a decoded HEIC copy.
- AVIF/WebP encoding depends on the browser — the 1×1 canvas detection surfaces the amber warning when unsupported.
- PNG and BMP hide the quality control because those paths are lossless.
- Transparent areas become white for JPEG/WebP/AVIF — flatten first if you need a specific matte, or export PNG to keep alpha.
- GIF input converts the first frame only; a note under the file name warns you before converting.
- The results delta is signed: a "+N%" means the output grew (common when targeting PNG or BMP), not that something failed.
- "Skipped n files" means some picks were outside the allowlist — the rest of the batch still loaded.
Format Converter FAQ
Which input formats are accepted?
JPEG, PNG, WebP, AVIF, BMP, GIF, and HEIC/HEIF. The dropzone, Change file, and Add More inputs share one explicit allowlist, and anything else gets a skip toast.
How many files can I convert at once?
Up to 50 per batch (MAX_BATCH_SIZE). Beyond that the extra picks are cut with a "You can only process up to 50 images at a time" toast.
How does HEIC work if my browser cannot decode it?
heic2any decodes the file locally into a PNG. A single HEIC decodes on select so the preview works; batch HEIC files decode one by one during conversion while the inline progress bar and the row spinner show where the run is.
Can I download everything at once?
Yes — batch results include "Download All (ZIP)", which packs converted_images.zip client-side with duplicate names renamed (photo.jpg, photo_2.jpg…).
Does it support TIFF output?
No — the Output Format list is JPEG, PNG, WebP, AVIF, and BMP.
Why did transparent areas turn white?
JPEG, WebP, and AVIF draws get a white background fill before drawImage, flattening alpha.
Is anything uploaded?
No — heic2any decoding, canvas toBlob conversion, and the ZIP build all run entirely in your browser.