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}