一张 1920 × 1080 的 24 位 BMP 接近 6 MB。同一张图以质量 90 保存为 JPEG,通常不到 500 KB。二者相差近十倍,这正是 BMP 仍出没于老式扫描仪、医疗软件和 Windows 内部组件,却通常需要转换后才能派上用场的原因。
BMP 的核心优势就是简单。要做好转换,需要知道这种简单性什么时候是优势,什么时候是短板,以及哪种目标格式才真正适合当前任务。
BMP 为什么还在
BMP 用极小的头部开销存储像素。没有霍夫曼表、没有 DEFLATE 状态机、没有色度子采样。对于嵌入式系统、遗留 Windows 工具,以及"读取头部、复制字节"即可搞定的场景,这种简单性确实是优势。
把它挤出日常使用的也是同样的缺点:
- 没有有效压缩。 未压缩 BMP 体积巨大。RLE 变体存在,但很少能赢过现代编解码器。
- 没有可靠的 Alpha 通道。 32 位 BMP 的 Alpha 字节在不同工具间支持不一致。
- 自底向上的行序。 大多数 BMP 从图像底部向上存储行,这对期望自上而下数据的处理流程会增加一个小转换步骤。
- 没有元数据生态。 经典头部不支持 EXIF、ICC 配置文件,也没有动画。
用于归档或兼容性,BMP 没问题。用于网页、邮件、移动端或追求存储效率的场景,它就得换成别的格式。
选择正确的输出格式
在运行命令或写代码之前,先确定你最看重什么。
| 目标格式 | 适用场景 | 取舍 |
|---|---|---|
| JPG | 照片、预览、任何屏幕展示 | 有损,但文件极小 |
| PNG | 图形、截图、需要透明度的内容 | 无损,照片比 JPG 大 |
| WebP | 现代网页、应用、任何在意带宽的场景 | 比 JPG/PNG 更小,浏览器支持广泛 |
如果你要转换一份带文字和图表的扫描文档,PNG 能保持边缘锐利。如果转换来自旧设备的照片,JPG 或 WebP 更合适。用于网页分发,WebP 通常在体积上胜出。
我们的浏览器端 BMP 转 JPG、BMP 转 PNG 和 BMP 转 WebP 转换器可以本地处理这三种情况——文件不会离开你的设备。
在 Windows 上转换
画图
- 用画图打开 BMP。
- 选择文件 > 另存为。
- 选择 JPEG 图片、PNG 图片 或 WebP 图像。
- 保存。
画图只能应付单张图片。没有质量调节,也支持不了批量处理,所以不适合整个文件夹。
PowerShell(ImageMagick)
从官网安装 ImageMagick 后:
magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp
批量转换某个文件夹:
Get-ChildItem *.bmp | ForEach-Object {
magick $_.FullName ($_.BaseName + ".jpg")
}
不借助外部工具的 PowerShell
Windows 10 和 11 内置 .NET 图像栈。这种方式支持 BMP 转 JPG 和 PNG,但 WebP 需要额外库:
Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("input.bmp")
$img.Save("output.jpg", [System.Drawing.Imaging.ImageFormat]::Jpeg)
$img.Dispose()
在 macOS 上转换
预览
- 用预览打开 BMP。
- 选择文件 > 导出。
- 从格式下拉框中选择目标格式。
- 如需输出 JPEG,可调整质量。
预览快速且私密,但和画图一样只能单文件处理。
终端使用 sips
sips 内置于 macOS,支持 BMP、JPEG、PNG 和 TIFF:
sips -s format jpeg input.bmp --out output.jpg
sips -s format png input.bmp --out output.png
WebP 需要 ImageMagick 或 Homebrew 的 webp 包提供的 cwebp:
brew install webp
# cwebp 不能直接读取 BMP,先转成 PNG
sips -s format png input.bmp --out temp.png
cwebp temp.png -o output.webp
rm temp.png
批量 shell 循环
for f in *.bmp; do
sips -s format jpeg "$f" --out "${f%.bmp}.jpg"
done
在 Linux 上转换
ImageMagick
sudo apt install imagemagick
magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp
调整 JPEG 质量:
magick input.bmp -quality 90 output.jpg
批量转换
for f in *.bmp; do
magick "$f" "${f%.bmp}.jpg"
done
如果你只需要最小的 WebP 输出,直接用 cwebp:
for f in *.bmp; do
cwebp -q 85 "$f" -o "${f%.bmp}.webp"
done
用代码转换
如果你需要在应用、流水线或后端服务里转换图片,直接调用库通常比调用 ImageMagick 命令更简洁。
TypeScript / Node.js
使用 sharp。它支持 BMP 输入,并可输出 JPG、PNG 和 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")
在浏览器里无法运行 sharp,我们的 BMP 转 WebP 转换器使用 WebAssembly 在客户端完成解码和编码。
PHP
如果启用了 GD 扩展,PHP 内置了图像函数。
<?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 标准库本身不读 BMP,但 golang.org/x/image/bmp 包可以。输出使用 image/jpeg、image/png 和 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 和 WebP 用同样的模式,分别调用 png.Encode 和 webp.Encode。
Java
Java 的 ImageIO 原生支持读取 BMP。输出 WebP 需要额外库,例如 webp-imageio 或 cwebp 绑定。
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);
}
}
如需更精细地控制 JPEG 质量,使用 JPEGImageWriteParam API。
Python
配合 Pillow,Python 是转换 BMP 最省事的选择。
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)
如果需要保留透明度输出为 PNG,不要强制转 RGB:
with Image.open("input.bmp") as img:
img.save("output.png")
常见陷阱
- 索引色 BMP。 8 位或更低位的 BMP 使用调色板。如果没有显式转换,某些解码器返回的是调色板索引而非 RGB 值。在 Pillow 中,保存为 JPEG 或 WebP 前用
img.convert("RGB")可解决。 - 自底向上方向。 大多数库会自动处理,但如果你手写 BMP 解码器,要记住正高度字段表示行自下而上存储。
- JPEG 默认质量。 许多工具默认 75–80。用于全屏观看的照片,90 更安全;用于缩略图,70–80 足够。
- WebP 兼容性。 WebP 浏览器支持很好,但在某些旧版桌面图片查看器中仍可能无法打开。如果目标是 Windows 原生应用,PNG 或 JPG 更安全。
不同场景该用什么
- 遗留归档: 保留原始 BMP。存储便宜,丢失原始版本不划算。
- 网页上传: 转换为 WebP。如果需要兜底格式,再保留一份 JPG。
- 印刷或编辑工作流: PNG 保持无损,避免压缩伪影。
- 邮件和即时通讯: JPG 是最安全的通用格式。
如果你想快速转换,又懒得安装软件、敲命令或上传文件,可以直接用我们的 BMP 转 JPG、BMP 转 PNG 和 BMP 转 WebP 转换器。所有处理都在浏览器内完成,文件自始至终留在你的机器上。



