v145 · Web APIs · Media · demo
Migration Guide
Drop a .bmp file to instantly check whether it uses the removed BI_JPEG or BI_PNG compression variants that Chrome 145 no longer decodes. The parser reads the DIB header directly, reports the compression field, and gives you step-by-step migration options.
Chrome 145 removed: BMP files with
BI_JPEG (compression = 4) or BI_PNG (compression = 5) in the BITMAPINFOHEADER will no longer decode. Standard BMP (BI_RGB, BI_RLE8, BI_RLE4) is unaffected.
Drop a .bmp file below (or click to browse) · see the parsed header fields · read the verdict
Drop a .bmp file here
or click to browse · only the first 64 bytes are read — no upload
BMP header analysis — —
Migration checklist — if you have affected files
1
Identify affected files in your asset pipeline
Search for .bmp files where bytes 30-33 (little-endian uint32) equal 4 (BI_JPEG) or 5 (BI_PNG). The code below does this in Node.js or the browser.
2
Convert to a standard web format
Re-encode to JPEG, PNG, WebP, or AVIF using ImageMagick, ffmpeg, or a build tool:
magick input.bmp output.webp
3
Or strip to plain BMP
Convert to standard BI_RGB BMP (no compression):
magick input.bmp -compress None output.bmp
4
Check user-submitted BMP content
If your app accepts BMP uploads, add server-side validation to reject BI_JPEG/BI_PNG variants before Chrome 145 silently shows a broken image.
// Detect BI_JPEG/BI_PNG BMP files in Node.js
import fs from 'fs';
function checkBMP(filepath) {
const buf = Buffer.alloc(34);
const fd = fs.openSync(filepath, 'r');
fs.readSync(fd, buf, 0, 34, 0);
fs.closeSync(fd);
if (buf[0] !== 0x42 || buf[1] !== 0x4D) return null; // not BMP
const compression = buf.readUInt32LE(30);
// BI_JPEG = 4, BI_PNG = 5
return { compression, affected: compression === 4 || compression === 5 };
}
// In the browser:
const arrayBuffer = await file.arrayBuffer();
const view = new DataView(arrayBuffer);
const compression = view.getUint32(30, true); // little-endian
const affected = compression === 4 || compression === 5;