image (Rust crate)
| Language | Rust |
|---|---|
| License | MIT or Apache 2.0 |
| Repository | github.com/image-rs/image |
| Documentation | docs.rs/image, codecs::bmp |
| Depends on | nothing for BMP (pure Rust) |
| Read / write | yes, 1-32 bit, RLE4, RLE8, bit fields / yes, 8-bit gray (palette), 24-bit RGB, 32-bit RGBA |
image is the high-level image library of the Rust ecosystem. Its BMP decoder handles palette images (1, 4 and 8 bits), 16-bit and 32-bit bit fields, RLE4 and RLE8 compression and top-down files, and also reads the BMP images inside ICO files. The encoder writes uncompressed files: 24-bit with a 40-byte header for RGB images, 32-bit with a V4 header and alpha mask for RGBA images, and 8-bit palette files for grayscale.
DynamicImage holds any decoded image; the imageops module has resize, crop, blur, flip and rotate.
Installation#
Shell
cargo add image
To compile only BMP support:
TOML
[dependencies]
image = { version = "0.25", default-features = false, features = ["bmp"] }
Basic usage: open, edit and save a BMP#
Rust
fn main() -> Result<(), image::ImageError> {
let img = image::open("in.bmp")?;
println!("{} x {}, {:?}", img.width(), img.height(), img.color());
let flipped = img.fliph();
flipped.save("out.bmp")?; // format from the extension
Ok(())
}
How to get BMP width and height without decoding#
Rust
let (width, height) = image::image_dimensions("in.bmp")?;
println!("{width} x {height}");
How to save a 24-bit BMP without alpha#
The color type of the image decides the BMP bit depth. Convert to RGB for a 24-bit file that every program reads:
Rust
let img = image::open("in.png")?;
img.to_rgb8().save("out24.bmp")?; // 24-bit, 40-byte header
img.to_rgba8().save("out32.bmp")?; // 32-bit with alpha, V4 header
img.to_luma8().save("gray8.bmp")?; // 8-bit with a gray palette
How to convert BMP to PNG#
Rust
let img = image::open("in.bmp")?;
img.save("out.png")?;
How to encode a BMP into memory#
Rust
use image::ImageFormat;
use std::io::Cursor;
let img = image::open("in.png")?.to_rgb8();
let mut bytes: Vec<u8> = Vec::new();
img.write_to(&mut Cursor::new(&mut bytes), ImageFormat::Bmp)?;
How to decode a BMP from bytes#
Rust
let bytes = std::fs::read("in.bmp")?;
let img = image::load_from_memory_with_format(&bytes, image::ImageFormat::Bmp)?;
Tips#
to_rgb8()drops alpha without blending. To flatten onto a background, draw the image on anRgbaImagefilled with the background color usingimageops::overlay, then callto_rgb8().image::ImageReader::open(path)?.with_guessed_format()?detects BMP by itsBMsignature, useful for.dibfiles.- Saving a 16-bit-per-channel image (e.g. from a 16-bit PNG) as BMP fails; convert with
to_rgb8()first.