PNG loses nothing, so the size drop depends on how repetitive your bitmap is
A BMP writes every pixel out in full. A PNG runs the same pixels through a filter pass and then Deflate, the algorithm inside ZIP files, and stores the result. No color is rounded, no detail is thrown away, and the decoded PNG matches the bitmap pixel for pixel. What changes is how much repetition Deflate finds. A 1920 by 1080 screenshot with flat window backgrounds and a few hundred distinct colors goes from 5.9 MB as a 24 bit BMP to somewhere between 100 and 300 KB. A photograph at the same dimensions, where neighbouring pixels are never quite equal, lands near 3 to 4 MB. Both PNGs are exact copies. Only one of them is small.
The ledger above measures the real byte count for each file rather than guessing from the dimensions, because the guess is unreliable in exactly the cases people care about. Two bitmaps with identical headers routinely produce PNGs a factor of twenty apart.
Three kinds of bitmap, three different outcomes
- Screenshots, diagrams, UI captures. The best case for PNG. Expect 90 to 98 percent saving on a 24 bit source. If the saving reads lower than 85 percent on a screenshot, the capture picked up a photo or a gradient wallpaper somewhere in frame.
- Scanned documents. Paper texture defeats Deflate. A 300 dpi scan of an A4 page saved as 24 bit BMP is about 26 MB and becomes a 6 to 10 MB PNG. Convert the scan to greyscale or 1 bit first if the content is black text, since the PNG shrinks by a further factor of ten once the scanner noise is gone.
- Photographs. PNG saves 30 to 50 percent at best. If the photo is going on a web page, the BMP to JPG converter gets the same picture under 500 KB. Use PNG for photos only when a later edit needs the exact pixels, such as compositing or archiving.
The fourth byte in a 32 bit bitmap is the part most converters get wrong
A 24 bit BMP stores blue, green and red for each pixel. A 32 bit BMP stores a fourth byte, and the original format specification marks it as reserved and tells writers to set it to zero. Later versions of the header, V4 and V5, added an alpha mask so the byte carries real transparency. Both conventions are in circulation, and the file itself rarely says which one applies.
Read the byte as alpha on a file where the writer zeroed it, and every pixel becomes fully transparent. The PNG opens as an empty checkerboard. Ignore the byte on a file where it holds a real alpha channel, and a logo with soft edges comes out with a hard black or white halo. The Decide per file setting handles both by reading the whole channel before committing: if every alpha byte is zero, the image is treated as opaque and the header column says so. If the bytes vary, they are kept. The two fixed settings exist for the exceptions, such as a file where a broken exporter wrote 255 everywhere except the pixels it meant to hide.
Files with a real alpha mask in a V4 or V5 header skip the guess entirely, since the mask is authoritative.
Color key transparency, for sprites and icons drawn before alpha existed
Game sprites, toolbar icons and cursor sets from the 8 bit and 16 bit era carried no alpha at all. Transparency was a convention: one palette entry, nearly always pure magenta #ff00ff, meant "draw nothing here". The rendering code skipped those pixels at blit time. Convert such a file to PNG the ordinary way and the magenta comes through as a solid backdrop.
Tick Make one color transparent and pixels matching the swatch get an alpha of zero. The tolerance slider widens the match for files where the backdrop was resaved through a lossy step at some point and the magenta drifted a few values. Keep tolerance at zero for clean 8 bit sources, since a widened match starts eating pinks inside the artwork. The Use corner pixel button reads the top left pixel of the first file in the batch, which is where the backdrop color sits on almost every sprite sheet ever made.
The key applies after alpha decoding, so a 32 bit file with real transparency and a magenta backdrop gets both removed.
Bitmaps this decoder opens that your browser will not
Browsers ship a BMP decoder, but a narrow one. Drop an RLE compressed bitmap into a browser tab and most render a broken image icon. This page does not hand the file to the browser. The decoder reads the header bytes directly and produces the pixels itself, which widens the set of files the conversion accepts:
- 1, 4 and 8 bit indexed files with a palette, including palettes shorter than the bit depth implies (the
colorsUsedheader field). - RLE8 and RLE4 run length encoded files, including delta and end of line escape codes. Common output from old Windows Paint and from game asset pipelines.
- 16 bit in 5-5-5 and 5-6-5 layouts, and any other channel mask in a BITFIELDS header.
- Top-down files with a negative height, which some capture tools write.
- OS/2 core headers, 12 bytes long with 3 byte palette entries.
- V4 and V5 headers with explicit alpha masks.
If the decoder cannot read a file, it tells you which header field it stopped on, then hands the bytes to the browser as a last attempt. A file the browser opens after the decoder failed is a file worth reporting, and the header column says which path produced the PNG.
Reading the header column
Each row shows the dimensions, the bit depth, the compression flag, the row order, and for indexed files the palette length. Two of these fields predict the size of the source exactly: BMP pads every row to a multiple of four bytes, so a 24 bit file of width w and height h weighs 54 + h * (floor((24 * w + 31) / 32) * 4) bytes, give or take a palette or a longer header. When the file on disk is much larger than the formula gives, something appended data after the pixel array, usually an ICC profile or a stray copy of the file, and the PNG will not carry it.
Where this converter stops
- Embedded JPEG and PNG. The BMP spec allows compression values 4 and 5, which wrap a JPEG or PNG stream inside a bitmap container for printer drivers. These are rejected with a message. If you have one, rename the payload or open it in an image editor.
- PNG output is 32 bit RGBA, always. The browser's PNG encoder writes eight bits per channel with an alpha channel, whatever the source depth. An 8 bit indexed bitmap therefore becomes a truecolor PNG, and a 1 bit fax page becomes a truecolor PNG. Deflate recovers most of the waste, but a palette aware encoder would produce a file two to four times smaller for indexed sources. Run the result through the PNG optimizer if the byte count matters.
- No compression level control. The encoder picks its own Deflate settings. There is no slider because the browser exposes none.
- Memory. Decoding happens in RAM at four bytes per pixel, per file, with the batch decoded sequentially. A 10,000 by 10,000 bitmap needs 400 MB of working memory and will fail on phones. Files over 8,000 pixels on the long edge are refused up front rather than crashing the tab.
- Metadata. BMP has none to speak of, and none is invented. The PNG carries no text chunks, no timestamps, no color profile.
- ICC profiles in V5 headers are ignored. Colors are written as untagged sRGB.
