image (Rust crate)
| Language | Rust |
|---|---|
| License | MIT or Apache 2.0 |
| Repository | github.com/image-rs/image |
| Documentation | docs.rs/image |
| Depends on | pure Rust codecs (the png crate for PNG) |
| Read / write | yes / yes, 8 and 16-bit gray, gray-alpha, RGB, RGBA; palette images are expanded |
image is the high-level image library of the Rust ecosystem. It opens and saves PNG, JPEG, GIF, WebP, BMP, ICO, TIFF, TGA, QOI, AVIF and more, all through pure Rust codecs by default. DynamicImage holds any decoded image; ImageBuffer (e.g. RgbaImage) gives typed pixel access. The imageops module has resize, crop, blur, flip, rotate and color operations.
For PNG it uses the png crate. It doesn’t expose text chunks or keep palettes (palette images decode to RGB or RGBA); use png directly for that.
Installation#
Shell
cargo add image
To compile only PNG support:
TOML
[dependencies]
image = { version = "0.25", default-features = false, features = ["png"] }
Basic usage: open, resize and save a PNG#
Rust
use image::imageops::FilterType;
fn main() -> Result<(), image::ImageError> {
let img = image::open("in.png")?;
println!("{} x {}, {:?}", img.width(), img.height(), img.color());
let thumb = img.resize(400, 400, FilterType::Lanczos3); // fits inside 400x400
thumb.save("out.png")?; // format from the extension
Ok(())
}
How to get PNG width and height without decoding#
Rust
let (width, height) = image::image_dimensions("in.png")?;
println!("{width} x {height}");
How to set PNG compression level#
Create a PngEncoder and pass it to write_with_encoder:
Rust
use image::codecs::png::{CompressionType, FilterType, PngEncoder};
use std::fs::File;
use std::io::BufWriter;
let img = image::open("in.png")?;
let out = BufWriter::new(File::create("small.png")?);
let encoder = PngEncoder::new_with_quality(out, CompressionType::Best, FilterType::Adaptive);
img.write_with_encoder(encoder)?;
How to create a PNG from pixels#
Rust
use image::{Rgba, RgbaImage};
let mut img = RgbaImage::new(256, 256);
for (x, y, pixel) in img.enumerate_pixels_mut() {
*pixel = Rgba([x as u8, y as u8, 128, 255]);
}
img.save("gradient.png")?;
How to convert PNG to JPEG or WebP#
JPEG has no alpha channel, so convert to RGB first:
Rust
let img = image::open("in.png")?;
img.to_rgb8().save("out.jpg")?; // JPEG, default quality 75
img.save("out.webp")?; // lossless WebP
For a specific JPEG quality use image::codecs::jpeg::JpegEncoder::new_with_quality(writer, 85).
How to decode a PNG from memory#
Rust
let bytes: &[u8] = include_bytes!("logo.png");
let img = image::load_from_memory_with_format(bytes, image::ImageFormat::Png)?;
Tips#
to_rgb8()drops the alpha channel without blending. To flatten onto a background, create anRgbaImagefilled with the background color, draw the image on it withimageops::overlay, then callto_rgb8().image::ImageReader::open(path)?.with_guessed_format()?detects the format from the file contents instead of the extension.- Set limits on an
ImageReader(reader.limits(...)) before decoding untrusted files.