#graphics #embedded-graphics #bmp #bitmap #image

no-std tinybmp

No-std, low memory footprint BMP image loader

6 releases

0.3.0-alpha.1 Dec 27, 2020
0.2.3 May 26, 2020
0.2.2 Mar 20, 2020
0.2.1 Feb 17, 2020
0.1.0 Mar 3, 2019

#261 in Embedded development

Download history 212/week @ 2021-01-09 123/week @ 2021-01-16 133/week @ 2021-01-23 131/week @ 2021-01-30 112/week @ 2021-02-06 182/week @ 2021-02-13 142/week @ 2021-02-20 186/week @ 2021-02-27 105/week @ 2021-03-06 92/week @ 2021-03-13 150/week @ 2021-03-20 124/week @ 2021-03-27 132/week @ 2021-04-03 211/week @ 2021-04-10 202/week @ 2021-04-17 131/week @ 2021-04-24

572 downloads per month
Used in 8 crates (3 directly)


468 lines


Build Status Crates.io Docs.rs embedded-graphics on Matrix


A small BMP parser designed for embedded, no-std environments but usable anywhere. Beyond parsing the image header, no other allocations are made.

To use tinybmp without embedded-graphics the raw data for individual pixels in an image can be accessed using the methods provided by the RawBmp struct.


Using Bmp to draw a BMP image

If the color format inside the BMP file is known at compile time the Bmp type can be used to draw an image to an embedded-graphics draw target. The BMP file used in this example uses 16 bits per pixel with a RGB565 format.

use embedded_graphics::{image::Image, prelude::*};
use tinybmp::Bmp;

let bmp_data = include_bytes!("../tests/chessboard-8px-color-16bit.bmp");

// Load 16 BPP 8x8px image.
// Note: The color type is specified explicitly to match the format used by the BMP image.
let bmp = Bmp::<Rgb565>::from_slice(bmp_data).unwrap();

// Draw the image with the top left corner at (10, 20) by wrapping it in
// an embedded-graphics `Image`.
Image::new(&bmp, Point::new(10, 20)).draw(&mut display)?;

Using DynamicBmp to draw a BMP image

If the exact color format used in the BMP file isn't known at compile time, for example to read user supplied images, the DynamicBmp can be used. Because automatic color conversion will be used the drawing performance might be degraded in comparison to Bmp.

use embedded_graphics::{image::Image, prelude::*};
use tinybmp::DynamicBmp;

let bmp_data = include_bytes!("../tests/chessboard-8px-color-16bit.bmp");

// Load BMP image with unknown color format.
// Note: There is no need to explicitly specify the color type.
let bmp = DynamicBmp::from_slice(bmp_data).unwrap();

// Draw the image with the top left corner at (10, 20) by wrapping it in
// an embedded-graphics `Image`.
Image::new(&bmp, Point::new(10, 20)).draw(&mut display)?;

Accessing the raw image data

The RawBmp struct provides methods to access lower level information about a BMP file, like the BMP header or the raw image data. An instance of this type can be created by using from_slice or by accessing the underlying raw object of a Bmp or DynamicBmp object by using as_raw.

use embedded_graphics::prelude::*;
use tinybmp::{RawBmp, Bpp, Header, RawPixel};

let bmp = RawBmp::from_slice(include_bytes!("../tests/chessboard-8px-24bit.bmp"))
    .expect("Failed to parse BMP image");

// Read the BMP header
    &Header {
        file_size: 314,
        image_data_start: 122,
        bpp: Bpp::Bits24,
        image_size: Size::new(8, 8),
        image_data_len: 192,
        channel_masks: None,

// Check that raw image data slice is the correct length (according to parsed header)
assert_eq!(bmp.image_data().len(), bmp.header().image_data_len as usize);

// Get an iterator over the pixel coordinates and values in this image and load into a vec
let pixels: Vec<RawPixel> = bmp.pixels().collect();

// Loaded example image is 8x8px
assert_eq!(pixels.len(), 8 * 8);


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~20K SLoC