What it does
This tool converts an image from one format to another, including turning images into multi-resolution .ico files (16/32/48/256px) for use as favicons or Windows app icons.
- Client-side (๐ป): for PNG, JPG, WebP, BMP, and GIF (first frame) โ everything happens instantly in your browser using the Canvas API. Nothing is uploaded.
- Server-side (๐ฅ๏ธ): for formats browsers cannot decode/encode natively โ HEIC/HEIF, TIFF, AVIF, ICO, and more reliable SVG rasterization โ the file is uploaded to the server, converted using
sharp(built onlibvips) plus a small dedicated encoder/decoder for the.icocontainer format, and the result is sent back to you. The file is processed in memory and discarded immediately after โ it is never written to disk or stored.
The tool automatically detects which mode a given input file needs, and lets you override it manually if you want to compare both.
Try it
Supported formats
| Format | As input | As output | Processing |
|---|---|---|---|
| PNG | โ | โ | Client or server |
| JPG / JPEG | โ | โ | Client or server |
| WebP | โ | โ | Client or server |
| BMP | โ | โ | Client or server |
| GIF | โ | โ (client) | Client reads first frame only; server can too |
| SVG | โ | โ | Rasterized as input, more reliably on the server |
| HEIC / HEIF | โ | โ | Server only โ no browser decodes this natively |
| TIFF | โ | โ | Server only |
| AVIF | โ | โ | Server only (encoding); some browsers can display it |
| ICO | โ | โ | Server only โ output is a multi-resolution icon (16/32/48/256px) |
| PSD | โ | โ | Not an image format decoders understand โ unsupported everywhere |
| RAW (CR2/NEF/ARW/DNG) | โ | โ | Requires a dedicated camera-raw decoder โ unsupported everywhere |
How it works
Client-side path
- The chosen file is loaded into an
<img>element using the browser's built-in decoder (PNG, JPG, WebP, GIF first frame, BMP, SVG). - It's drawn onto a
<canvas>. - The canvas is re-encoded into the target format with
canvas.toBlob().
Nothing leaves your device in this path.
Server-side path
- The file is read as a base64 data URL and sent to
/api/tools/image-format-converteras JSON. tools/image-format-converter/server.jsdecodes it into aBuffer. HEIC/HEIF is pre-decoded withheic-convert, and.icoinput is decoded withdecode-ico(picking the largest embedded frame); both then flow throughsharp/libvipsfor the requested output (PNG, JPEG, WebP, TIFF, AVIF). For.icooutput, the source image is resized bysharpinto the four standard icon sizes (256, 48, 32, 16px) and packed into a single.icocontainer by a small built-in encoder (lib/simple-ico-encoder.js) โ sharp/libvips can't write the ICO container format itself.- The result is sent back as a base64 data URL and rendered/downloaded exactly like the client-side result.
The server does not persist the uploaded image anywhere โ it's held in memory only for the duration of the request.
Notes
- PSD and camera RAW formats (CR2, NEF, ARW, DNG) are not supported by either path โ they need proprietary/dedicated decoders beyond what
libvipsor browsers provide. - ICO output always bundles four sizes (16ร16, 32ร32, 48ร48, 256ร256) into one file, resizing/letterboxing (with transparency) as needed โ this matches how Windows favicons/app icons are typically packaged.
- Converting a transparent image to JPG/BMP/AVIF-without-alpha fills transparent areas with white.
- Animated GIFs: only the first frame is used, on both paths โ this tool does not create or preserve animation.
- Prefer the client-side path whenever your format is supported there โ it's faster and keeps your image entirely private. Use the server-side path only for the formats that genuinely require it.