Skip to main content

vox_format/
image.rs

1//! Integration with `image` crate.
2
3use image::{
4    Rgba,
5    RgbaImage,
6};
7
8use crate::types::{
9    Color,
10    Palette,
11};
12
13impl From<Color> for Rgba<u8> {
14    fn from(color: Color) -> Self {
15        Rgba(color.into())
16    }
17}
18
19impl From<Rgba<u8>> for Color {
20    fn from(color: Rgba<u8>) -> Self {
21        color.0.into()
22    }
23}
24
25impl Palette {
26    /// Converts the palette into an RGBA image. The image will have dimensions
27    /// 256 (width) x 1 (height).
28    pub fn as_image(&self) -> RgbaImage {
29        RgbaImage::from_fn(256, 1, |x, _| {
30            let color = self.colors[x as usize];
31            color.into()
32        })
33    }
34
35    /// Converts a RGBA image to a color palette. Regardless of shape of the
36    /// image, the first 256 pixels (row-first order) will be used. If there
37    /// aren't enough pixels, the rest of the palette will be transparent.
38    ///
39    /// # Note
40    ///
41    /// VOX palettes have 256 colors, but VOX files only store the last 255
42    /// colors. The first color is always assumed to be fully transparent. Thus
43    /// any color for the first palette entry will be lost once the palette is
44    /// written to file.
45    pub fn from_image(image: &RgbaImage) -> Palette {
46        let mut colors = [Color::default(); 256];
47        image
48            .pixels()
49            .take(256)
50            .copied()
51            .enumerate()
52            .for_each(|(i, px)| colors[i] = px.into());
53
54        Palette { colors }
55    }
56}