Thanks to visit codestin.com
Credit goes to lib.rs

2 releases

0.24.2 Oct 16, 2025
0.24.1 Oct 14, 2025
0.24.0 Oct 5, 2025

#515 in Images

WTFPL and maybe CC-PDDC

91KB
2.5K SLoC

feim is a crate designed with some clues from libgoimg, which in turn was heavily influeced by the API of Go's image package. One of the goals of feim was to increase the flexibility users had to work with images, namely rolling their own custom serialization routines, color formats and image formats.

Encoding

Here is a simple white background being saved to a file out.png:

use std::fs::File;
use std::io::{self, BufWriter};

use feim::buffer::RawPixBuf;
use feim::image::png::Png;
use feim::color::Rgb;
use feim::image::ImageMut;
use feim::serialize::EncodeSpecialized;

const DIM: usize = 250;

fn main() -> io::Result<()> {
    let output = File::create("out.png")?;
    let output = BufWriter::new(output);

    let mut image = RawPixBuf::new(DIM, DIM);
    draw_image(&mut image);

    let opts = Default::default();
    Png::encode_specialized(output, opts, &image)
}

fn draw_image(buf: &mut RawPixBuf<Rgb>) {
    const WHITE: Rgb = Rgb { r: 255, g: 255, b: 255 };

    for y in 0..DIM {
        for x in 0..DIM {
            buf.pixel_set(x, y, WHITE);
        }
    }
}

Decoding

Decoding images with feim is as simples as:

use std::io::{self, BufReader, BufWriter, Write};

use feim::buffer::RawPixBuf;
use feim::image::jpeg::Jpeg;
use feim::color::Nrgba64Be;
use feim::image::Format;
use feim::image::farbfeld::{Farbfeld, FarbfeldDecodeOptions};
use feim::serialize::{try_format, EncodeSpecialized, Decode};

fn main() -> io::Result<()> {
    let stdin = io::stdin();
    let stdin_lock = stdin.lock();
    let mut stdin_reader = BufReader::new(stdin_lock);

    let stdout = io::stdout();
    let stdout_lock = stdout.lock();
    let mut stdout_writer = BufWriter::new(stdout_lock);

    let formats: [(usize, &dyn Format); 2] = [
        (0, &Farbfeld),
        (1, &Jpeg),
    ];

    match try_format(&mut stdin_reader, formats) {
        Ok(Some(0)) => {
            let opts = FarbfeldDecodeOptions {
                check_header: false,
            };
            let image: RawPixBuf<Nrgba64Be> = Farbfeld::decode(stdin_reader, opts)?;
            let _ = write!(&mut stdout_writer, "{:#?}", image);
            Ok(())
        },
        Ok(Some(1)) => {
            let image = Jpeg::decode(stdin_reader, ())?;
            let _ = write!(&mut stdout_writer, "{:#?}", image);
            Ok(())
        },
        Ok(Some(_)) => unreachable!(),
        Ok(None) => panic!("Image format not supported"),
        Err(e) => Err(e),
    }
}

Note that you should be using BuiltInFormat as the tag type passed to try_format instead of integers. A readily available iterator with all built-in formats is available under built_in_formats_iter.

Dependencies

~0–1.5MB
~19K SLoC