A 1920 × 1080 BMP saved at 24 bits weighs just under 6 MB. The same image as a quality-90 JPEG is usually under 500 KB. That roughly ten-to-one gap is why BMP files still show up in legacy scanners, medical software, and Windows internals — and why they usually need to be converted before they can be used anywhere else.
BMP's real advantage is simplicity. Converting it well means knowing when that simplicity helps, when it gets in the way, and which target format actually fits the job.
Why BMP Still Exists
BMP stores pixels with minimal header overhead. No Huffman tables, no DEFLATE state machine, no chroma subsampling. For embedded systems, legacy Windows tools, and any situation where the whole task is "read the header, copy the bytes," that simplicity is genuinely useful.
The same limitations are what pushed it out of everyday use:
- No effective compression. Uncompressed BMPs are large. RLE variants exist, but they rarely beat modern codecs.
- No reliable alpha channel. The 32-bit BMP alpha byte is inconsistently supported across tools.
- Bottom-up row order. Most BMPs store rows from the bottom of the image upward, which adds a small conversion step for anything expecting top-down data.
- No metadata ecosystem. No EXIF, no ICC profile support in the classic header, no animation.
For archival or compatibility, BMP is fine. For web, email, mobile, or storage efficiency, it needs to become something else.
Picking the Right Output Format
Before running a command or writing code, decide what you are optimizing for.
| Target | Use when | Trade-off |
|---|---|---|
| JPG | Photographs, previews, any screen display | Lossy, but file sizes are tiny |
| PNG | Graphics, screenshots, anything needing transparency | Lossless, larger than JPG for photos |
| WebP | Modern web, apps, anywhere bandwidth matters | Smaller than JPG/PNG, broad browser support |
If you are converting a scanned document with text and diagrams, PNG keeps edges sharp. If you are converting a photo from a legacy device, JPG or WebP is the right call. For web delivery, WebP usually wins on size.
Our browser-based BMP to JPG, BMP to PNG, and BMP to WebP converters handle all three cases locally — the file never leaves your device.
Converting on Windows
Paint
- Open the BMP in Paint.
- Choose File > Save as.
- Select JPEG picture, PNG picture, or WebP image.
- Save.
Paint works for one-off files. It offers no quality control and no batch option, so it is not practical for folders of images.
PowerShell (ImageMagick)
Install ImageMagick from the official installer, then:
magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp
For batch conversion in a folder:
Get-ChildItem *.bmp | ForEach-Object {
magick $_.FullName ($_.BaseName + ".jpg")
}
PowerShell without external tools
Windows 10 and 11 include the .NET imaging stack. This works for BMP to JPG and PNG, but not WebP without an extra library:
Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("input.bmp")
$img.Save("output.jpg", [System.Drawing.Imaging.ImageFormat]::Jpeg)
$img.Dispose()
Converting on macOS
Preview
- Open the BMP in Preview.
- Choose File > Export.
- Pick the format from the dropdown.
- Adjust quality for JPEG if needed.
Preview is fast and private, but like Paint it handles one file at a time.
Terminal with sips
sips is built into macOS and supports BMP, JPEG, PNG, and TIFF:
sips -s format jpeg input.bmp --out output.jpg
sips -s format png input.bmp --out output.png
WebP requires ImageMagick or cwebp from the webp Homebrew package:
brew install webp
# cwebp does not read BMP directly, so convert to PNG first
sips -s format png input.bmp --out temp.png
cwebp temp.png -o output.webp
rm temp.png
Batch shell loop
for f in *.bmp; do
sips -s format jpeg "$f" --out "${f%.bmp}.jpg"
done
Converting on Linux
ImageMagick
sudo apt install imagemagick
magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp
Adjust JPEG quality:
magick input.bmp -quality 90 output.jpg
Batch conversion
for f in *.bmp; do
magick "$f" "${f%.bmp}.jpg"
done
If you only need the smallest possible WebP output, use cwebp directly:
for f in *.bmp; do
cwebp -q 85 "$f" -o "${f%.bmp}.webp"
done
Converting with Code
When you need conversion inside an application, pipeline, or backend service, calling a library is usually cleaner than shelling out to ImageMagick.
TypeScript / Node.js
Use sharp. It handles BMP input and outputs JPG, PNG, and WebP.
import sharp from "sharp"
async function convertBmp(
input: string,
output: string,
format: "jpg" | "png" | "webp"
) {
await sharp(input)
.toFormat(format, format === "jpg" ? { quality: 90 } : undefined)
.toFile(output)
}
await convertBmp("input.bmp", "output.jpg", "jpg")
await convertBmp("input.bmp", "output.png", "png")
await convertBmp("input.bmp", "output.webp", "webp")
In the browser, where you cannot run sharp, our BMP to WebP converter uses WebAssembly to decode and encode entirely on the client.
PHP
PHP has built-in image functions if the GD extension is enabled.
<?php
function bmpToJpg(string $input, string $output, int $quality = 90): void {
$image = imagecreatefrombmp($input);
imagejpeg($image, $output, $quality);
imagedestroy($image);
}
function bmpToPng(string $input, string $output): void {
$image = imagecreatefrombmp($input);
imagepng($image, $output);
imagedestroy($image);
}
function bmpToWebp(string $input, string $output, int $quality = 90): void {
$image = imagecreatefrombmp($input);
imagewebp($image, $output, $quality);
imagedestroy($image);
}
bmpToJpg("input.bmp", "output.jpg");
bmpToPng("input.bmp", "output.png");
bmpToWebp("input.bmp", "output.webp");
Go
Go's standard library does not read BMP, but golang.org/x/image/bmp does. For output, use image/jpeg, image/png, and golang.org/x/image/webp.
package main
import (
"image/jpeg"
"image/png"
"os"
"golang.org/x/image/bmp"
"golang.org/x/image/webp"
)
func bmpToJpg(input, output string, quality int) error {
f, err := os.Open(input)
if err != nil {
return err
}
defer f.Close()
img, err := bmp.Decode(f)
if err != nil {
return err
}
out, err := os.Create(output)
if err != nil {
return err
}
defer out.Close()
return jpeg.Encode(out, img, &jpeg.Options{Quality: quality})
}
PNG and WebP follow the same pattern with png.Encode and webp.Encode.
Java
Java's ImageIO reads BMP out of the box. For WebP output you need a library such as webp-imageio or cwebp bindings.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class BmpConverter {
public static void bmpToJpg(String input, String output, float quality) throws IOException {
BufferedImage image = ImageIO.read(new File(input));
File out = new File(output);
ImageIO.write(image, "jpg", out);
}
public static void bmpToPng(String input, String output) throws IOException {
BufferedImage image = ImageIO.read(new File(input));
File out = new File(output);
ImageIO.write(image, "png", out);
}
}
For finer JPEG quality control, use the JPEGImageWriteParam API.
Python
With Pillow, Python is the most straightforward way to convert BMP to any common format.
from PIL import Image
with Image.open("input.bmp") as img:
img.convert("RGB").save("output.jpg", quality=90)
with Image.open("input.bmp") as img:
img.save("output.png")
with Image.open("input.bmp") as img:
img.save("output.webp", quality=90)
For transparency-aware conversion to PNG, preserve the original mode instead of forcing RGB:
with Image.open("input.bmp") as img:
img.save("output.png")
Common Pitfalls
- Indexed-color BMPs. 8-bit or lower BMPs use a palette. Some decoders return palette indexes instead of RGB values if you do not explicitly convert. In Pillow,
img.convert("RGB")solves this before saving to JPEG or WebP. - Bottom-up orientation. Most libraries handle this automatically, but if you are writing a manual BMP decoder, remember that a positive height field means rows are stored bottom-up.
- JPEG quality defaults. Many tools default to 75–80. For photos that will be viewed full screen, 90 is a safer default. For thumbnails, 70–80 is fine.
- WebP compatibility. WebP has excellent browser support but still fails in some older desktop image viewers. If the destination is a native Windows app, PNG or JPG is safer.
What to Use Where
- Legacy archives: Keep the original BMP. Storage is cheap; losing the canonical version is not.
- Web uploads: Convert to WebP. If you need a fallback, keep a JPG copy.
- Print or editing workflows: PNG keeps the image lossless and avoids compression artifacts.
- Email and messaging: JPG is the safest universal format.
If you want a fast path with no install, no command line, and no upload, use our BMP to JPG, BMP to PNG, and BMP to WebP converters. Everything runs in the browser, so the file stays on your machine from start to finish.



