clessy-rs/src/commands/sunny.rs

47 lines
1.5 KiB
Rust

use anyhow::{anyhow, Result};
use image::{codecs::png::PngEncoder, ColorType, ImageBuffer, ImageEncoder, Rgba, RgbaImage};
use imageproc::{
drawing::{draw_filled_rect_mut, draw_text_mut, text_size},
rect::Rect,
};
use rusttype::{Font, Scale};
const FONT_DATA: &[u8] = include_bytes!("../../bindata/Textile.ttf");
const COLOR_BG: Rgba<u8> = Rgba([0u8, 0u8, 0u8, 255u8]);
const COLOR_TEXT: Rgba<u8> = Rgba([255u8, 255u8, 255u8, 255u8]);
const TEXT_SCALE: Scale = Scale { x: 42.0, y: 42.0 };
pub struct Sunny<'a> {
font: Font<'a>,
}
impl Sunny<'_> {
pub fn init() -> Result<Self> {
let font = Font::try_from_bytes(FONT_DATA).ok_or_else(|| anyhow!("invalid font data"))?;
Ok(Self { font })
}
pub fn generate(&self, message: &str) -> Result<Vec<u8>> {
let mut img = ImageBuffer::new(800, 480);
let (width, height) = img.dimensions();
draw_filled_rect_mut(&mut img, Rect::at(0, 0).of_size(width, height), COLOR_BG);
let (text_w, text_h) = text_size(TEXT_SCALE, &self.font, message);
draw_text_mut(
&mut img,
COLOR_TEXT,
(width as i32) / 2 - text_w / 2,
(height as i32) / 2 - text_h / 2,
TEXT_SCALE,
&self.font,
message,
);
let mut png_buffer = Vec::new();
let encoder = PngEncoder::new(&mut png_buffer);
encoder.write_image(img.as_raw(), width, height, ColorType::Rgba8)?;
Ok(png_buffer)
}
}