Choosing a bit depth when you convert PNG to BMP
BMP stores pixels the way a memory buffer stores them, one after another, with no compression in the usual case. A PNG shrinks a flat blue square to a few hundred bytes. The same square as a 24-bit BMP costs three bytes per pixel whether the image is a photograph or a solid colour. Once you know the file size is arithmetic rather than a surprise, the depth selector above stops being a setting and becomes the only choice worth making.
The file size is a formula, not an estimate
Every uncompressed BMP is a small header followed by rows of pixels, each row padded up to a multiple of four bytes. Nothing else. For a 1920 by 1080 image the four depths land here:
32-bit 1920 x 4 x 1080 + 122 bytes = 7.91 MB 24-bit 1920 x 3 x 1080 + 54 bytes = 5.93 MB 8-bit 1920 x 1 x 1080 + 1078 bytes = 1.98 MB 1-bit 240 x 1080 + 62 bytes = 253 KB
The 8-bit row shows the palette cost: 256 entries of four bytes each sit between the header and the pixels, so a tiny 8-bit BMP carries a kilobyte of colour table before a single pixel. For a 16 by 16 icon that palette outweighs the image. The size chips beside the depth buttons run this same arithmetic on your file the moment it loads, so you read the real number rather than a guess.
Rows are padded, and the padding is invisible
Each row of pixel data is rounded up to a four byte boundary. A 99 pixel wide 24-bit image needs 297 bytes per row and gets 300, wasting three bytes on every line for nothing. Widths divisible by four avoid it at 24-bit, and 32-bit output never pads at all because four bytes per pixel is already aligned. This is why an odd width sometimes produces a file slightly larger than the multiplication suggests.
Rows are also stored bottom to top. A standard BMP writes the last row of the image first, signalled by a positive height field in the header. Some capture tools write a negative height to mean top-down instead. Both are legal, and a decoder ignoring the sign is the reason a BMP occasionally opens upside down. Files from this page use the positive, bottom-up form, which every reader handles.
What each depth costs you
| Depth | Header written | Good for | What breaks |
|---|---|---|---|
| 32-bit | BITMAPV4HEADER, 108 bytes, with alpha bitfields | Overlays and sprites where transparency has to survive | Paint, some older Windows dialogs and a few embedded readers drop the alpha byte and render black |
| 24-bit | BITMAPINFOHEADER, 40 bytes, BI_RGB | Anything opening a BMP anywhere. The safe answer | Transparency is gone, flattened onto whatever background colour you set |
| 8-bit | 40 bytes plus a 256 entry palette | Screenshots, logos, line art, UI captures, embedded displays | Photographs band across skies and skin unless dithering is on |
| 1-bit | 40 bytes plus a two entry palette | Masks, stencils, fax and thermal output, e-ink panels | Everything except the shapes. Midtones collapse to one side of the threshold |
Transparency has two possible endings
PNG carries an alpha channel and BMP mostly does not, so something has to happen to those pixels. At 24-bit and below, the converter composites the image onto the background colour you pick, matting semi-transparent edges into it. Pick the colour the image will sit on. A logo matted onto white and then placed on a dark panel shows a pale halo around every antialiased edge, and no later edit removes it cleanly.
At 32-bit the alpha byte survives, written with a BITMAPV4HEADER and explicit channel masks. Test the file in the program it is destined for before trusting it. Windows Paint saves 32-bit BMP files and still displays alpha as black, which trips up plenty of people who assume the file is broken. If the target is unclear, 24-bit with a matching background colour disappoints nobody.
Palette output, dithering, and where RLE8 pays off
The 8-bit path picks colours by median cut, splitting the image histogram along its widest colour axis until it has your palette size, then averaging each group. Screenshots and flat artwork survive this untouched, since they rarely hold more than a few hundred distinct colours to begin with. Gradients are where it shows: skies and shadows step into visible bands.
Dithering scatters the quantisation error into neighbouring pixels, so a band becomes a stipple. It reads better at normal viewing distance and worse under magnification. Turn it off for screenshots and UI mockups, where clean flat regions matter more than smooth ramps, and turn it on for anything photographic.
RLE8 is the one compression mode in wide BMP use. It encodes runs of identical palette indices, so it wins on flat artwork and loses on noise. A test bar of mostly one colour drops from 3078 bytes to 1640 with RLE8 on. Dither the same image and the runs vanish along with the saving. RLE8 also has a cost worth knowing: some older viewers, printer drivers and embedded parsers read only BI_RGB and reject the file outright.
Palette size and file size are separate things. Dropping from 256 to 16 colours writes a shorter colour table and saves a few hundred bytes, nothing more. Each pixel still spends a full byte. The reason to reduce is longer identical runs for RLE8, or a target device with a fixed palette.
Reading the preview honestly
The result panel is not the source image with a filter over it. It is a redraw of the exact pixels written into the BMP, so 8-bit banding and 1-bit thresholding appear on screen as they will appear in the file. Turn on Sharp pixels to disable browser smoothing and inspect quantisation at close range, which is the only reliable way to judge a dither pattern.
The ratio line under the result compares the BMP against the PNG you started with. Expect it to read larger almost every time. A PNG of a screenshot commonly beats a 24-bit BMP by ten to one. Converting is about compatibility with a program insisting on the format, never about saving space.
When BMP is the right answer
- A program refuses anything else. Older Windows utilities, industrial and medical control software, and plenty of legacy inspection tools accept BMP alone.
- Embedded and firmware work. Splash screens, e-ink displays and microcontroller panels favour a format needing no decoder. Raw rows load straight into a framebuffer.
- Pipelines wanting a decoded intermediate. Feeding raw frames to a tool with no PNG support avoids repeated decode steps.
- Windows resource files. Toolbar strips, cursors and dialog bitmaps still use BMP, and mask work is 1-bit territory.
For a website, an app asset, or anything travelling over a network, keep the PNG. BMP earns its place at the point where a receiving program leaves you no choice.
Limits worth knowing before you rely on this
- Metadata does not survive. BMP has nowhere to keep EXIF, ICC profiles, text chunks or creation dates, so anything the PNG carried is dropped. Read it first with the metadata viewer if it matters.
- Colour management is out of scope. Pixels are written as sRGB values with no embedded profile. A PNG tagged with a wide gamut profile converts by its raw numbers, which shifts the appearance in a colour managed viewer.
- Only the first frame of an APNG is read. The browser decoder hands over one still image, and animation has no place in BMP.
- 16-bit channels are flattened to 8. A 48-bit PNG loses precision during decode, before the encoder sees it. BMP has no 16-bit-per-channel mode in common use anyway.
- Memory is the practical ceiling. A 40 megapixel image at 32-bit needs roughly 160MB in a single buffer, which is where mobile browsers give up. The page refuses anything above that mark rather than crashing the tab.
- Interlaced and unusual PNG variants depend on the browser. Decoding runs through the browser image pipeline, so a file the browser refuses fails here too, with no fallback parser behind it.
Everything runs in this tab. The file is read into a canvas, encoded to BMP bytes in JavaScript, and offered as a download from browser memory. No upload happens at any point, which matters when the image is a screenshot of something private.
