BMP to PNG Converter

Drop a folder of bitmaps, get a PNG for each one and a ledger showing what every file weighed before and after. The decoder reads indexed, RLE, 16 bit and 32 bit bitmaps itself, so files your browser refuses to open still convert. Nothing leaves your device.

BMP to PNG batch converter

  • Own BMP decoder, RLE included
  • Alpha byte policy for 32 bit files
  • Batch download as one ZIP

Drop BMP files here or tap to browse

Any number of files. Each one converts as soon as the header is read.

No bitmap handy?
Fourth byte in 32 bit files

Per file means: alpha bytes all zero are read as opaque, anything else is read as real transparency.

Color key transparency
#ff00ff
exact match

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

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:

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

Questions about converting bitmaps to PNG

Transparency, file sizes that went the wrong way, and what the batch download contains.

Will the PNG look identical to the BMP?

Yes, pixel for pixel. PNG compression is lossless, so every color value in the bitmap is stored exactly and comes back exactly when the PNG is decoded. The only deliberate changes are the ones you switch on: the alpha byte policy and the color key. With the color key off and the alpha setting on Always opaque, the PNG is a byte exact copy of the bitmap pixels.

My converted PNG is completely transparent. What happened?

The source was a 32 bit BMP whose fourth byte was zero on every pixel, and the alpha setting was on Always alpha, so every pixel was read as fully transparent. Switch to Decide per file or Always opaque and convert again. The header column reports "alpha bytes all zero, treated as opaque" when the automatic rule fires, so you know which files were affected.

Why is a PNG larger than the BMP it came from?

Two causes. The bitmap was 8 bit or lower, so it stored one byte per pixel, while the PNG output is always 32 bit RGBA before compression. On noisy content such as dithered images, Deflate cannot recover the difference and the PNG ends up bigger. The other cause is an RLE compressed source, which was already compact. In both cases a PNG optimizer with palette reduction brings the file back down, and the ledger shows a negative saving so the case is visible rather than hidden.

Does this convert a batch of BMP files at once?

Yes. Drop as many files as you like, or select a whole folder in the file picker. Each one decodes and encodes in turn and appears in the ledger as it finishes. Download all packages every PNG into a single ZIP built in the browser. The ZIP uses store mode with no extra compression, since PNG data does not compress further, so it opens in every archive tool including the built-in Windows and macOS extractors.

How do I make the white background of a BMP transparent?

Set the color key swatch to #ffffff, tick Make one color transparent, and convert. Keep in mind the key matches by color, not by position. White pixels inside the artwork, such as highlights or text, turn transparent too. Fine for a logo on a plain white backdrop, wrong for a photo. For a photo, a background remover with edge detection is the right tool.

Are my files uploaded anywhere?

No. The page loads one JavaScript file and then does everything on your device: header parsing, pixel decoding, PNG encoding and ZIP packaging. No request carries image data, and switching the network off after the page loads changes nothing. The converted files exist only in your browser memory until you download them or close the tab.