All formats

image

LanguageRust
LicenseMIT or Apache 2.0
Repositorygithub.com/image-rs/image
Documentationimage::codecs::ico on docs.rs
Depends onpure Rust (png crate for PNG entries); the ico feature is on by default
Read / writeyes (largest entry only) / yes, PNG entries, several frames

The image crate treats ICO as one more format: image::open("app.ico") returns a DynamicImage of the best entry (largest area, then highest bit depth). It decodes BMP and PNG entries. You can’t pick another entry through the crate; use the ico crate for that.

For writing, IcoEncoder::encode_images takes a list of IcoFrames, so you can resize one image to several sizes with image’s own resize functions and write a multi-size icon in a few lines. Frames are PNG-encoded (or you pass pre-encoded PNG/BMP bytes), and each must be 1 to 256 pixels wide and high.

Installation#

Shell
cargo add image

Basic usage: convert ICO to PNG#

Rust
fn main() -> Result<(), image::ImageError> {
    let img = image::open("app.ico")?;  // largest entry
    println!("{} x {}", img.width(), img.height());
    img.save("app.png")?;
    Ok(())
}

How to create a multi-size favicon.ico from one image#

Rust
use image::codecs::ico::{IcoEncoder, IcoFrame};
use image::imageops::FilterType;
use image::ExtendedColorType;
use std::fs::File;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let logo = image::open("logo.png")?;
    let mut frames = Vec::new();
    for size in [256u32, 48, 32, 16] {
        let rgba = logo.resize_exact(size, size, FilterType::Lanczos3).to_rgba8();
        frames.push(IcoFrame::as_png(rgba.as_raw(), size, size, ExtendedColorType::Rgba8)?);
    }
    IcoEncoder::new(File::create("favicon.ico")?).encode_images(&frames)?;
    Ok(())
}

How to save a single-size ICO#

save picks the encoder from the extension and writes one entry. The image must be 256x256 or smaller:

Rust
let img = image::open("logo.png")?;
img.resize(256, 256, image::imageops::FilterType::Lanczos3).save("app.ico")?;

How to get the icon size without decoding#

Rust
let (w, h) = image::image_dimensions("app.ico")?;  // size of the largest entry

Tips#