Batch Image Converter

Many pictures in, one tidy ZIP out.

  • Stays on device
  • Sizes before, after
  • One ZIP download
A short stack of blank rounded picture frames on a desk beside a small rounded box with its lid open, in rose and teal light.

The guide

Converting a picture is re-drawing it: what survives a change of format and what quietly does not

A format change decodes every pixel and writes a new file from scratch, so the honest questions are which pixels came back, how many bytes it cost, and what was left behind.

  • 30 to 50 dB typical PSNR for lossy 8-bit pictures
  • 54 bytes the headers in front of a plain 24-bit BMP
  • 93.0% smaller the example sky, PNG to WebP at quality 85
  • 4 bytes every BMP row is padded to a multiple of this
Read the full guide Fold the guide 7 min · 18 sources

There is no such thing as changing a picture’s format in place. A PNG does not become a JPEG the way a word becomes bold. Every converter, whatever its buttons say, does the same three things: it decodes the old file into a grid of colour values, it may change that grid, and it encodes the grid again under the rules of the new format. The old file contributes pixels and nothing else, unless the converter goes out of its way to copy more.

That plain fact explains almost everything people find surprising about conversion. It explains why a photo can come out sideways, why a transparent logo can land on a black square, why a file can grow when it was meant to shrink, and why the camera details and location tags of a photo usually vanish. It also gives a fair way to judge any converter: decode what it wrote, compare it with what went in, and count the bytes.

Decoding comes first, and it already makes choices

A phone held upright usually stores its picture sideways and adds a small note saying how to turn it. That note lives in the Exif block, which a JPEG carries in its APP1 segment. The tag is number 274, written 0x0112, and its value 6 means the picture should be turned 90 degrees clockwise before it is shown. A decoder that ignores the note hands over a sideways grid, and the converter then writes a sideways file that has lost the note that would have fixed it.

Browsers let a page decide. The createImageBitmap call takes an imageOrientation option whose value “from-image” applies the Exif orientation and whose value “none” ignores it. A careful converter asks for the turn at decode time, so the new file is upright in its own pixels and needs no note at all. The example batch includes a JPEG stored 540 pixels wide with tag 6; it comes out 360 by 540, red band at the top.

Decoding also settles colour. The decoder turns the file’s values into the browser’s working space, which for an ordinary page is sRGB. From then on the converter is holding plain numbers.

Lossless, lossy, and what the encoder adds

The second half is where formats really differ. PNG is lossless: the numbers written are the numbers read back, and it carries a full alpha channel for transparency. BMP is simpler still. It mostly stores the numbers raw, blue then green then red for each pixel, row after row, each row padded with zeros to a multiple of 4 bytes. Uncompressed BMP files are large for that reason, and a general compressor such as ZIP can often shrink them a great deal.

JPEG is the opposite bargain. It converts colour into brightness and two colour-difference channels, usually halves the resolution of the colour channels in both directions, cuts the picture into 8 by 8 blocks and rounds away detail the eye notices least. The quality setting controls how hard that rounding bites. Typical compression is about ten to one with a loss that most people accept. JPEG has no alpha channel at all, and every fresh save rounds the picture again, so editing and re-saving one JPEG piles up generation loss.

WebP offers both kinds. Its lossy mode is built on the VP8 video codec and its lossless mode on a different scheme; both can carry alpha. MDN’s guide puts lossy WebP at about 25 to 35 percent smaller than JPEG of similar look, and lossless WebP at about 26 percent smaller than PNG. AVIF, from the Alliance for Open Media with version 1.0.0 dated 19 February 2019, does the same job with the AV1 codec, but a browser that can show AVIF cannot always write it.

Browsers encode through the canvas, and the HTML standard is blunt about the edge cases. If the requested type is not supported, the encoder must silently write PNG instead. If the format has no alpha, the picture must be laid onto opaque black. If the format can carry a colour profile, the file must include one describing the canvas colour space. Each rule has a consequence. A converter has to check the type of the file it got back rather than trust that the request worked; it has to paint a background of its own choosing under transparent areas before writing a JPEG; and it has to decide whether it wants the profile the encoder added.

Measuring the round trip

The only convincing check is to decode the new file and compare it with the pixels that went in. For PNG and BMP the comparison is simple and strict: every value must match. For lossy formats some difference is the whole point, so the useful number is how large it is. Peak signal-to-noise ratio is the standard summary. Take the mean of the squared differences over the red, green and blue values, call it the MSE, and compute ten times the base-ten logarithm of 255 squared divided by that MSE. Identical pictures give infinity; typical lossy results for 8-bit pictures fall between 30 and 50 dB.

A worked example makes the numbers concrete. The tool’s example sky is drawn in code at 720 by 450 pixels and saved as a PNG of 81,436 bytes. Converted in a Chromium browser to WebP at quality 85, it becomes 5,674 bytes, 93.0% smaller, and decodes back at 43.6 dB. The same picture as JPEG at quality 85 takes 14,414 bytes at 43.5 dB. As a 24-bit BMP it takes 972,054 bytes, which is exactly 54 bytes of headers plus 450 rows of 2,160 bytes. Load the examples and switch formats to see the same figures; another browser’s encoder will land near them, not on them.

The same batch shows where lossy formats go wrong. The 48 by 32 pixel art in the examples has hard edges and flat colours, the worst case for block rounding and halved colour channels. At quality 85 it comes back at 28.2 dB as WebP and 27.3 dB as JPEG, under the 30 dB line, while PNG returns it exactly in a smaller file than the BMP it started as. Screenshots, line art, charts and pixel art belong in a lossless format. Photographs, with their noise and soft gradients, are where lossy formats earn their savings.

Transparency deserves the same care. A logo with soft shadow edges has pixels that are partly see-through. Written as PNG or WebP, those pixels keep their alpha. Written as JPEG, they must be blended onto something, and the honest way to judge the result is to blend both pictures onto the same background before comparing. That is how the tool measures PSNR: red, green and blue after laying each picture over the chosen background, so a transparent pixel counts as it will actually look.

BMP has a twist that makes it a good test of any writer. Its height field is signed. A positive height means the rows are stored bottom-up, the first row in the file being the bottom of the picture; a negative height means top-down. Write the rows top-down while storing a positive height and every reader will show the picture upside down, a mistake that is invisible in the file’s size and obvious the moment it is decoded. Transparency in BMP needs the larger 108-byte BITMAPV4HEADER, with masks that name which byte of each 32-bit pixel is alpha.

What does not survive, and what the batch adds

Because the encoder only receives pixels, much of what the original file carried is simply not passed on. Exif camera settings and GPS tags, PNG text chunks, XMP blocks and the original’s embedded colour profile all belong to the old file. The Exif article notes that most image editors damage or remove Exif to some extent on saving, for much the same reason.

That is not the same as a clean file. The encoder may write containers of its own, because the canvas rules ask for a profile wherever a format can carry one: PNG has an iCCP chunk for it, the WebP container defines optional ICCP, EXIF and XMP chunks, and a JPEG can hold a profile in an APP2 segment. A converter that cares strips those after encoding and scans the bytes again. In this tool’s Chromium tests the JPEG and WebP encoders each added a profile and the PNG encoder added none; both profiles were removed before the files were checked.

Ancillary PNG chunks are marked by a lower-case first letter, so a reader may skip them and a careful writer may drop them. Two limits are worth stating plainly. Re-encoding is not a privacy tool: whatever the picture shows, a face or a street sign or a screen, stays in it. And a check of known containers is only that; this tool reads PNG, JPEG, WebP and BMP structure but does not look inside AVIF files.

A batch adds its own bookkeeping. Many output files need distinct names, so a second “holiday” becomes “holiday-2”. Memory has to stay flat across hundreds of pictures, which means decoding one file at a time and closing each bitmap as soon as it is encoded; MDN describes close as releasing the bitmap’s graphical resources. Finally the files travel together. A ZIP archive puts a local header in front of each stored file and a central directory at the end that lists every name, size, offset and CRC-32 checksum. Pictures are already compressed, so storing them as they are costs little, and checking every checksum before saving costs less than finding a damaged file later.

None of this is exotic. It is the ordinary discipline of a converter that says what it did: pixels decoded upright, a format chosen for the content, a measured difference, a list of what was stripped, and a size before and after for every file. The format name on the button matters less than those receipts.

Sources

Every source consulted for this guide. Links checked October 22, 2026.

  1. Window: createImageBitmap() method MDN Web Docs
  2. OffscreenCanvas: convertToBlob() method MDN Web Docs
  3. HTMLCanvasElement: toBlob() method MDN Web Docs
  4. ImageBitmap: close() method MDN Web Docs
  5. Image file type and format guide MDN Web Docs
  6. HTML Standard WHATWG
  7. Portable Network Graphics (PNG) Specification (Third Edition) W3C
  8. WebP Container Specification Google for Developers
  9. BMP file format Wikipedia
  10. JPEG - Wikipedia Wikipedia
  11. WebP - Wikipedia Wikipedia
  12. AVIF - Wikipedia Wikipedia
  13. Peak signal-to-noise ratio Wikipedia
  14. Exif - Wikipedia Wikipedia
  15. TIFF tags Library of Congress
  16. EXIF Tags ExifTool by Phil Harvey
  17. ZIP (file format) Wikipedia
  18. APPNOTE.TXT - .ZIP File Format Specification PKWARE