pub mod quantize;
pub use image;
use image::{GenericImageView, Pixel};
use num_traits::cast::ToPrimitive;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Write;
pub struct PbnConfig {
pub x_offset: u32,
pub y_offset: u32,
pub max_length: usize,
}
impl PbnConfig {
pub fn new() -> PbnConfig {
PbnConfig {
x_offset: 0,
y_offset: 0,
max_length: 400,
}
}
pub fn x_offset(self, x_offset: u32) -> PbnConfig {
PbnConfig { x_offset, ..self }
}
pub fn y_offset(self, y_offset: u32) -> PbnConfig {
PbnConfig { y_offset, ..self }
}
pub fn max_length(self, max_length: usize) -> PbnConfig {
PbnConfig { max_length, ..self }
}
pub fn run<I: GenericImageView>(&self, image: &I) -> Vec<String> {
let &PbnConfig {
x_offset,
y_offset,
max_length,
} = self;
let mut colors: BTreeMap<[u8; 4], BTreeSet<(u32, u32)>> = BTreeMap::new();
for (x, y, p) in image.pixels() {
let [r, g, b, a] = p.to_rgba().data;
if a.to_u8().unwrap() != 0 {
colors
.entry([
r.to_u8().unwrap(),
g.to_u8().unwrap(),
b.to_u8().unwrap(),
a.to_u8().unwrap(),
])
.or_insert_with(BTreeSet::new)
.insert((x, y));
}
}
let mut commands = Vec::new();
let mut buf;
let mut pixbuf = String::new();
for (&[r, g, b, a], pixels) in &colors {
buf = String::with_capacity(max_length);
write!(buf, "#{:02x}{:02x}{:02x}{:02x} ", r, g, b, a).unwrap();
for &(x, y) in pixels {
pixbuf.clear();
write!(pixbuf, "{},{};", x + x_offset + 1, y + y_offset + 1).unwrap();
if buf.len() + pixbuf.len() > max_length {
commands.push(buf);
buf = String::with_capacity(max_length);
write!(buf, "#{:02x}{:02x}{:02x}{:02x} ", r, g, b, a).unwrap();
}
buf.push_str(&pixbuf);
}
commands.push(buf);
}
commands
}
}
impl Default for PbnConfig {
fn default() -> PbnConfig {
PbnConfig::new()
}
}