47 lines
1.5 KiB
Rust
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)
|
|
}
|
|
}
|