在浏览器端用 Ja vaScript 把 PNG 图片转成 BMP 格式,这个需求听起来有点复古,但在某些特定场景下(比如需要兼容老旧系统、或者做底层图像处理)还真挺管用。核心思路其实不复杂:先用 Canvas 把 PNG 的像素数据读出来,再按照 BMP 文件的二进制规范,把这些数据重新组装一遍,最后生成一个可下载的 BMP 文件。下面直接给出一套完整可运行的方案。
先说说几个关键知识点
- BMP 的文件结构:说白了就是三部分——14 字节的文件头、40 字节的信息头、然后是像素数据本体。
- 像素格式转换:Canvas 读出来的像素是 RGBA 顺序,但 BMP 要求的是 BGRA(而且默认忽略 Alpha 通道),顺序得调换一下。
- 字节对齐:BMP 有个比较老的规矩——每一行像素数据的字节数必须是 4 的倍数,不够就补零。这个细节容易踩坑。
完整实现的代码
PNG 转 BMP
怎么用?很简单
- 把上面这段代码保存成一个 .html 文件,用浏览器打开。
- 点击文件选择框,选一张 PNG 图片。
- 点击「转换为 BMP」按钮,浏览器就会自动下载转换好的 BMP 文件。
几个容易忽略的坑
- 跨域限制:如果是在线环境使用,得保证图片服务器返回了
Access-Control-Allow-Origin头,否则 Canvas 会被"污染",拿不到像素数据。 - 位深度:上面的代码生成的是 24 位 BMP,不带 Alpha 通道。BMP 其实也支持 32 位带透明通道,但兼容性差一些。如果确实需要保留透明度,可以把信息头的位深度改成 32,然后在像素数据里保留 Alpha 值。
- 性能:处理 4K 以上的大图时可能会有点卡顿,毕竟是在主线程里逐像素操作。如果真有这个需求,可以考虑用 Web Worker 做分片处理。
- 兼容性:所有现代浏览器(Chrome、Firefox、Edge、Safari)都能正常运行。不过 IE 就算了,它对 Blob 和 DataView 的支持不太行,真要兼容的话还得额外做 polyfill。