silence_core/avif/
encoding.rs

1//! Provides AV1 encoding for higher data efficiency via [`ravif`].
2
3use image::GenericImageView;
4use ravif::{EncodedImage, Encoder, Img};
5
6///
7/// Encodes a **formatted** image with the AV1 format.
8///
9/// **If you are looking to encode a [`crate::cam::Webcam::get_frame`]'s returned frame [`encode_raw_image`] is the one to use.**
10///
11/// # Behavior
12/// The **formatted** image is re-encoded with the settings the user passes in with the [`Encoder`] argument.
13/// The encoded image ([`ravif::EncodedImage`]) is returned from the image.
14///
15/// # Error
16/// Will return an error if the image format could not be guessed correctly or if the image had incorrect proerties (Eg.: Invalid size).
17///
18pub fn encode_image(encoder: Encoder, image: &[u8]) -> anyhow::Result<EncodedImage> {
19    //Parse image from bytes
20    let parsed_image = image::load_from_memory(image)?;
21
22    //Iter over the pixels
23    let colors = parsed_image
24        .pixels()
25        .map(|(_, _, color)| ravif::RGB8::new(color.0[0], color.0[1], color.0[2]))
26        .collect::<Vec<ravif::RGB8>>();
27
28    //Encode image
29    let encoded_image: EncodedImage = encoder.encode_rgb(Img::new(
30        colors.as_slice(),
31        parsed_image.width() as usize,
32        parsed_image.height() as usize,
33    ))?;
34
35    Ok(encoded_image)
36}
37
38///
39/// Encodes a raw image with the AV1 format
40///
41/// # Behavior
42/// The image is encoded with the settings the user passes in with the [`Encoder`] argument.
43/// The encoded image ([`EncodedImage`]) is returned from the raw image.
44///
45/// # Error
46/// If the image had incorrect proerties (Eg.: Invalid size).
47///
48pub fn encode_raw_image(
49    encoder: Encoder,
50    image: &[u8],
51    width: usize,
52    height: usize,
53) -> anyhow::Result<EncodedImage> {
54    //Iter over the raw pixels
55    let colors = image
56        .chunks_exact(3)
57        .map(|chunk| ravif::RGB8::new(chunk[0], chunk[1], chunk[2]))
58        .collect::<Vec<ravif::RGB8>>();
59
60    //Encode image
61    let encoded_image: EncodedImage =
62        encoder.encode_rgb(Img::new(colors.as_slice(), width, height))?;
63
64    Ok(encoded_image)
65}