Upload any image, resize it to exact pixel dimensions, and convert between PNG, JPEG, and WebP — all processed locally in your browser using libvips (via WebAssembly) for high-quality Lanczos resampling. Nothing is uploaded to a server.
Drop an image here or click to upload
Supports any browser-readable image: PNG, JPEG, GIF, WebP, BMP, SVG, etc.
| File name | - |
| MIME type | - |
| File size | - |
| Dimensions | - |
Set the output width and height in pixels. When the lock is active, changing one value automatically adjusts the other to preserve the original aspect ratio, preventing distortion.
Choose the image encoding for the output file. PNG is lossless and best for graphics, icons, or screenshots. JPEG uses lossy compression and is best for photographs. WebP is a modern format offering smaller files than JPEG at comparable quality.
Controls the lossy compression level. Higher values preserve more detail but produce larger files. Lower values reduce file size at the cost of visible artifacts. This setting only applies to JPEG and WebP.
This tool runs entirely in your browser. Your images are never sent to a server — all processing happens client-side using wasm-vips, a WebAssembly build of libvips, the same high-performance image processing library used by sharp (Node.js) and many server-side pipelines.
On first visit, the browser downloads a ~4.5 MB WebAssembly module
(vips.wasm) from a CDN and compiles it inside a
Web Worker. This keeps the UI responsive while the engine
initializes. Once loaded, the status badge turns green and the Resize button
becomes active. The browser caches the WASM file, so subsequent visits load
almost instantly.
When you upload or drop an image, the browser's
FileReader API reads it as both an ArrayBuffer
(sent to the worker for processing) and a data URL (used for the preview
thumbnail). The raw bytes are passed directly to libvips, which can decode
JPEG, PNG, WebP, TIFF, GIF, and many other formats natively.
The worker calls vips.Image.thumbnailBuffer(), which is
significantly more efficient than a naïve decode-then-resize pipeline.
For JPEG inputs, it exploits the format's built-in 2×/4×/8×
shrink-on-load, drastically reducing memory use and CPU time for large
downscales. The resampling kernel is Lanczos3, a
high-quality windowed sinc filter that preserves sharp edges and fine detail
far better than the bilinear interpolation used by the HTML Canvas API.
After resizing, libvips encodes the result into the chosen format:
When resizing, EXIF data (camera model, GPS coordinates, date/time, etc.)
is stripped from the output for privacy, while
ICC color profiles are preserved so images maintain
accurate color rendering across displays. This is controlled via the
ForeignKeep.icc flag in libvips.
The Strip EXIF Only button removes EXIF metadata from a JPEG without re-encoding. It works at the binary level: the JPEG file is parsed segment-by-segment, and any APP1/Exif segments are removed while the compressed image data is left completely untouched. This means zero generation loss — every pixel remains bit-identical to the original. The file size will decrease slightly (by the size of the removed metadata). This is ideal when you just want to strip GPS coordinates or camera info before sharing a photo.
The encoded bytes are transferred from the worker back to the main thread,
wrapped in a Blob, and turned into an object URL
(URL.createObjectURL). Clicking Download triggers the
browser's native file-save dialog.
Your image data never leaves the browser. The WASM engine, Web Worker, and all encoding happen in local memory. Refreshing or closing the page discards all data. The only network request is fetching the wasm-vips library itself from a CDN.